linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] wl1251 WMM support and minor fixes
@ 2009-11-26 15:08 Kalle Valo
  2009-11-26 15:08 ` [PATCH 01/12] wl1251: add tx queue status to debugfs Kalle Valo
                   ` (12 more replies)
  0 siblings, 13 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:08 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

Moi John, [1]

here are few patches for wl1251. Now there is WMM support and also some
minor fixes. The patchset applies on top of the wl1251 power save fixes I
sent earlier today.

These patches are not urgent.

[1] http://en.wiktionary.org/wiki/moi#Finnish 
    the only easy word in finnish

---

Kalle Valo (12):
      wl1251: add tx queue status to debugfs
      wl1251: print a debug message when tx_queue is full
      wl1251: fix error handling in wl1251_op_config()
      wl1251: reduce ELP wakeup timeout
      wl1251: simplify ELP wakeup time calculation
      wl1251: fix payload alignment
      wl1251: use __dev_alloc_skb() on RX
      wl1251: implement acx_ac_cfg to configure hardware queues
      wl1251: implement wl1251_acx_tid_cfg()
      wl1251: implement WMM
      wl1251: update tx_hdr when aliging skb in tx
      wl1251: enable WMM


 drivers/net/wireless/wl12xx/wl1251.h         |    1 
 drivers/net/wireless/wl12xx/wl1251_acx.c     |   69 +++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_acx.h     |   87 ++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_debugfs.c |   23 +++++++
 drivers/net/wireless/wl12xx/wl1251_init.c    |    5 +
 drivers/net/wireless/wl12xx/wl1251_init.h    |   47 ++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_main.c    |   50 ++++++++++++++-
 drivers/net/wireless/wl12xx/wl1251_ps.c      |    9 +--
 drivers/net/wireless/wl12xx/wl1251_rx.c      |   17 +++++
 drivers/net/wireless/wl12xx/wl1251_tx.c      |    9 +--
 drivers/net/wireless/wl12xx/wl1251_tx.h      |   17 +++++
 11 files changed, 323 insertions(+), 11 deletions(-)


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/12] wl1251: add tx queue status to debugfs
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
@ 2009-11-26 15:08 ` Kalle Valo
  2009-11-26 15:08 ` [PATCH 02/12] wl1251: print a debug message when tx_queue is full Kalle Valo
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:08 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Sometimes when debugging the state is good info.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251.h         |    1 +
 drivers/net/wireless/wl12xx/wl1251_debugfs.c |   23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 054533f..6301578 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -247,6 +247,7 @@ struct wl1251_debugfs {
 	struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
 
 	struct dentry *tx_queue_len;
+	struct dentry *tx_queue_status;
 
 	struct dentry *retry_count;
 	struct dentry *excessive_retries;
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
index a007230..0ccba57 100644
--- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -237,6 +237,27 @@ static const struct file_operations tx_queue_len_ops = {
 	.open = wl1251_open_file_generic,
 };
 
+static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf,
+				    size_t count, loff_t *ppos)
+{
+	struct wl1251 *wl = file->private_data;
+	char buf[3], status;
+	int len;
+
+	if (wl->tx_queue_stopped)
+		status = 's';
+	else
+		status = 'r';
+
+	len = scnprintf(buf, sizeof(buf), "%c\n", status);
+	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
+}
+
+static const struct file_operations tx_queue_status_ops = {
+	.read = tx_queue_status_read,
+	.open = wl1251_open_file_generic,
+};
+
 static void wl1251_debugfs_delete_files(struct wl1251 *wl)
 {
 	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
@@ -331,6 +352,7 @@ static void wl1251_debugfs_delete_files(struct wl1251 *wl)
 	DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
 
 	DEBUGFS_DEL(tx_queue_len);
+	DEBUGFS_DEL(tx_queue_status);
 	DEBUGFS_DEL(retry_count);
 	DEBUGFS_DEL(excessive_retries);
 }
@@ -431,6 +453,7 @@ static int wl1251_debugfs_add_files(struct wl1251 *wl)
 	DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
 
 	DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+	DEBUGFS_ADD(tx_queue_status, wl->debugfs.rootdir);
 	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
 	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
 


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/12] wl1251: print a debug message when tx_queue is full
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
  2009-11-26 15:08 ` [PATCH 01/12] wl1251: add tx queue status to debugfs Kalle Valo
@ 2009-11-26 15:08 ` Kalle Valo
  2009-11-26 15:08 ` [PATCH 03/12] wl1251: fix error handling in wl1251_op_config() Kalle Valo
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:08 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

This debug message was missing and caused incomplete log messages.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_main.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 2f50a25..e9fb2ca 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -395,6 +395,7 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	 * the queue here, otherwise the queue will get too long.
 	 */
 	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
+		wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
 		ieee80211_stop_queues(wl->hw);
 
 		/*


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/12] wl1251: fix error handling in wl1251_op_config()
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
  2009-11-26 15:08 ` [PATCH 01/12] wl1251: add tx queue status to debugfs Kalle Valo
  2009-11-26 15:08 ` [PATCH 02/12] wl1251: print a debug message when tx_queue is full Kalle Valo
@ 2009-11-26 15:08 ` Kalle Valo
  2009-11-26 15:08 ` [PATCH 04/12] wl1251: reduce ELP wakeup timeout Kalle Valo
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:08 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Not all return values were checked and one exit from function didn't put
firmware sleep after the error.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_main.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index e9fb2ca..8ba6742 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -641,20 +641,25 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
 		 * through the bss_info_changed() hook.
 		 */
 		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+		if (ret < 0)
+			goto out_sleep;
 	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
 		   wl->psm_requested) {
 		wl1251_debug(DEBUG_PSM, "psm disabled");
 
 		wl->psm_requested = false;
 
-		if (wl->psm)
+		if (wl->psm) {
 			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+			if (ret < 0)
+				goto out_sleep;
+		}
 	}
 
 	if (conf->power_level != wl->power_level) {
 		ret = wl1251_acx_tx_power(wl, conf->power_level);
 		if (ret < 0)
-			goto out;
+			goto out_sleep;
 
 		wl->power_level = conf->power_level;
 	}


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/12] wl1251: reduce ELP wakeup timeout
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (2 preceding siblings ...)
  2009-11-26 15:08 ` [PATCH 03/12] wl1251: fix error handling in wl1251_op_config() Kalle Valo
@ 2009-11-26 15:08 ` Kalle Valo
  2009-11-26 15:08 ` [PATCH 05/12] wl1251: simplify ELP wakeup time calculation Kalle Valo
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:08 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

The original TI driver uses 100 ms timeout ELP wakeup timeout, better
to use the same. Otherwise problems with wakeup might get unnoticed.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_ps.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 9931b19..54a2720 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -26,7 +26,8 @@
 #include "wl1251_cmd.h"
 #include "wl1251_io.h"
 
-#define WL1251_WAKEUP_TIMEOUT 2000
+/* in ms */
+#define WL1251_WAKEUP_TIMEOUT 100
 
 void wl1251_elp_work(struct work_struct *work)
 {


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/12] wl1251: simplify ELP wakeup time calculation
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (3 preceding siblings ...)
  2009-11-26 15:08 ` [PATCH 04/12] wl1251: reduce ELP wakeup timeout Kalle Valo
@ 2009-11-26 15:08 ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 06/12] wl1251: fix payload alignment Kalle Valo
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:08 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

The wakeup time calculation was too complicated, simplify it.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_ps.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
index 54a2720..851dfb6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -68,7 +68,7 @@ void wl1251_ps_elp_sleep(struct wl1251 *wl)
 
 int wl1251_ps_elp_wakeup(struct wl1251 *wl)
 {
-	unsigned long timeout;
+	unsigned long timeout, start;
 	u32 elp_reg;
 
 	if (!wl->elp)
@@ -76,6 +76,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
 
 	wl1251_debug(DEBUG_PSM, "waking up chip from elp");
 
+	start = jiffies;
 	timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
 
 	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
@@ -96,8 +97,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl)
 	}
 
 	wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
-		     jiffies_to_msecs(jiffies) -
-		     (jiffies_to_msecs(timeout) - WL1251_WAKEUP_TIMEOUT));
+		     jiffies_to_msecs(jiffies - start));
 
 	wl->elp = false;
 


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/12] wl1251: fix payload alignment
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (4 preceding siblings ...)
  2009-11-26 15:08 ` [PATCH 05/12] wl1251: simplify ELP wakeup time calculation Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-26 15:13   ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 07/12] wl1251: use __dev_alloc_skb() on RX Kalle Valo
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

mac80211 complained that in some cases IP payload was not aligned, this
happens if the 802.11 header is not aligned with four. In that case we have
to move entire packet to make the payload properly aligned.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_rx.c |   17 ++++++++++++++++-
 1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index f84cc89..04f3dcd 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/string.h>
 #include <linux/skbuff.h>
 #include <net/mac80211.h>
 
@@ -32,6 +33,9 @@
 #include "wl1251_cmd.h"
 #include "wl1251_acx.h"
 
+/* needs to be divisible by four because of DMA */
+#define WL1251_RX_ALIGNMENT	4
+
 static void wl1251_rx_header(struct wl1251 *wl,
 			     struct wl1251_rx_descriptor *desc)
 {
@@ -106,6 +110,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
 	struct sk_buff *skb;
 	struct ieee80211_rx_status status;
 	u8 *rx_buffer, beacon = 0;
+	unsigned char *from, *to;
 	u16 length, *fc;
 	u32 curr_id, last_id_inc, rx_packet_ring_addr;
 
@@ -126,12 +131,15 @@ static void wl1251_rx_body(struct wl1251 *wl,
 	if (wl->rx_current_buffer)
 		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
 
-	skb = dev_alloc_skb(length);
+	skb = dev_alloc_skb(length + WL1251_RX_ALIGNMENT);
 	if (!skb) {
 		wl1251_error("Couldn't allocate RX frame");
 		return;
 	}
 
+	/* for the case if payload is unaligned */
+	skb_reserve(skb, WL1251_RX_ALIGNMENT);
+
 	rx_buffer = skb_put(skb, length);
 	wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
 
@@ -140,6 +148,13 @@ static void wl1251_rx_body(struct wl1251 *wl,
 
 	fc = (u16 *)skb->data;
 
+	if (ieee80211_hdrlen(*fc) & 0x3) {
+		from = skb->data;
+		to = skb_push(skb, 2);
+		memmove(to, from, skb->len);
+		fc = (u16 *) skb->data;
+	}
+
 	if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
 		beacon = 1;
 


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/12] wl1251: use __dev_alloc_skb() on RX
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (5 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 06/12] wl1251: fix payload alignment Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 08/12] wl1251: implement acx_ac_cfg to configure hardware queues Kalle Valo
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

RX is handled in a workqueue therefore allocating for GFP_ATOMIC
is overkill and not required.

Based on a patch for wl1271 by Luis R. Rodriguez.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_rx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
index 04f3dcd..5731dd7 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -131,7 +131,7 @@ static void wl1251_rx_body(struct wl1251 *wl,
 	if (wl->rx_current_buffer)
 		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
 
-	skb = dev_alloc_skb(length + WL1251_RX_ALIGNMENT);
+	skb = __dev_alloc_skb(length + WL1251_RX_ALIGNMENT, GFP_KERNEL);
 	if (!skb) {
 		wl1251_error("Couldn't allocate RX frame");
 		return;


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/12] wl1251: implement acx_ac_cfg to configure hardware queues
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (6 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 07/12] wl1251: use __dev_alloc_skb() on RX Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 09/12] wl1251: implement wl1251_acx_tid_cfg() Kalle Valo
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Needed for WMM.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Reviewed-by: Janne Ylalehto <janne.ylalehto@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_acx.c  |   33 ++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_acx.h  |   32 ++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_init.c |    5 +++
 drivers/net/wireless/wl12xx/wl1251_init.h |   47 +++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_main.c |   27 +++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_tx.h   |   20 ++++++++++++
 6 files changed, 164 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index acfa086..b409c75 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -976,3 +976,36 @@ out:
 	kfree(acx);
 	return ret;
 }
+
+int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
+		      u8 aifs, u16 txop)
+{
+	struct wl1251_acx_ac_cfg *acx;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d "
+		     "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->ac = ac;
+	acx->cw_min = cw_min;
+	acx->cw_max = cw_max;
+	acx->aifsn = aifs;
+	acx->txop_limit = txop;
+
+	ret = wl1251_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("acx ac cfg failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
index 6523714..5679324 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.h
@@ -1166,6 +1166,36 @@ struct wl1251_acx_wr_tbtt_and_dtim {
 	u8  padding;
 } __attribute__ ((packed));
 
+struct wl1251_acx_ac_cfg {
+	struct acx_header header;
+
+	/*
+	 * Access Category - The TX queue's access category
+	 * (refer to AccessCategory_enum)
+	 */
+	u8 ac;
+
+	/*
+	 * The contention window minimum size (in slots) for
+	 * the access class.
+	 */
+	u8 cw_min;
+
+	/*
+	 * The contention window maximum size (in slots) for
+	 * the access class.
+	 */
+	u16 cw_max;
+
+	/* The AIF value (in slots) for the access class. */
+	u8 aifsn;
+
+	u8 reserved;
+
+	/* The TX Op Limit (in microseconds) for the access class. */
+	u16 txop_limit;
+} __attribute__ ((packed));
+
 /*************************************************************************
 
     Host Interrupt Register (WiLink -> Host)
@@ -1322,5 +1352,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
 int wl1251_acx_rate_policies(struct wl1251 *wl);
 int wl1251_acx_mem_cfg(struct wl1251 *wl);
 int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
+int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
+		      u8 aifs, u16 txop);
 
 #endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
index 5cb5733..5aad56e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.c
+++ b/drivers/net/wireless/wl12xx/wl1251_init.c
@@ -294,6 +294,11 @@ static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
 			goto out;
 	}
 
+	wl1251_acx_ac_cfg(wl, AC_BE, CWMIN_BE, CWMAX_BE, AIFS_DIFS, TXOP_BE);
+	wl1251_acx_ac_cfg(wl, AC_BK, CWMIN_BK, CWMAX_BK, AIFS_DIFS, TXOP_BK);
+	wl1251_acx_ac_cfg(wl, AC_VI, CWMIN_VI, CWMAX_VI, AIFS_DIFS, TXOP_VI);
+	wl1251_acx_ac_cfg(wl, AC_VO, CWMIN_VO, CWMAX_VO, AIFS_DIFS, TXOP_VO);
+
 out:
 	kfree(config);
 	return ret;
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
index b3b25ec..269cefb 100644
--- a/drivers/net/wireless/wl12xx/wl1251_init.h
+++ b/drivers/net/wireless/wl12xx/wl1251_init.h
@@ -26,6 +26,53 @@
 
 #include "wl1251.h"
 
+enum {
+	/* best effort/legacy */
+	AC_BE = 0,
+
+	/* background */
+	AC_BK = 1,
+
+	/* video */
+	AC_VI = 2,
+
+	/* voice */
+	AC_VO = 3,
+
+	/* broadcast dummy access category */
+	AC_BCAST = 4,
+
+	NUM_ACCESS_CATEGORIES = 4
+};
+
+/* following are defult values for the IE fields*/
+#define CWMIN_BK  15
+#define CWMIN_BE  15
+#define CWMIN_VI  7
+#define CWMIN_VO  3
+#define CWMAX_BK  1023
+#define CWMAX_BE  63
+#define CWMAX_VI  15
+#define CWMAX_VO  7
+
+/* slot number setting to start transmission at PIFS interval */
+#define AIFS_PIFS 1
+
+/*
+ * slot number setting to start transmission at DIFS interval - normal DCF
+ * access
+ */
+#define AIFS_DIFS 2
+
+#define AIFSN_BK  7
+#define AIFSN_BE  3
+#define AIFSN_VI  AIFS_PIFS
+#define AIFSN_VO  AIFS_PIFS
+#define TXOP_BK   0
+#define TXOP_BE   0
+#define TXOP_VI   3008
+#define TXOP_VO   1504
+
 int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
 int wl1251_hw_init_templates_config(struct wl1251 *wl);
 int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 8ba6742..4d335d6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1279,6 +1279,32 @@ static struct ieee80211_channel wl1251_channels[] = {
 	{ .hw_value = 13, .center_freq = 2472},
 };
 
+static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
+			     const struct ieee80211_tx_queue_params *params)
+{
+	struct wl1251 *wl = hw->priv;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
+				params->cw_min, params->cw_max,
+				params->aifs, params->txop);
+
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_supported_band wl1251_band_2ghz = {
 	.channels = wl1251_channels,
@@ -1299,6 +1325,7 @@ static const struct ieee80211_ops wl1251_ops = {
 	.hw_scan = wl1251_op_hw_scan,
 	.bss_info_changed = wl1251_op_bss_info_changed,
 	.set_rts_threshold = wl1251_op_set_rts_threshold,
+	.conf_tx = wl1251_op_conf_tx,
 };
 
 static int wl1251_register_hw(struct wl1251 *wl)
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
index 7c1c166..b7bead8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -26,6 +26,7 @@
 #define __WL1251_TX_H__
 
 #include <linux/bitops.h>
+#include "wl1251_acx.h"
 
 /*
  *
@@ -209,6 +210,25 @@ struct tx_result {
 	u8 done_2;
 } __attribute__ ((packed));
 
+static inline int wl1251_tx_get_queue(int queue)
+{
+	/* FIXME: use best effort until WMM is enabled */
+	return QOS_AC_BE;
+
+	switch (queue) {
+	case 0:
+		return QOS_AC_VO;
+	case 1:
+		return QOS_AC_VI;
+	case 2:
+		return QOS_AC_BE;
+	case 3:
+		return QOS_AC_BK;
+	default:
+		return QOS_AC_BE;
+	}
+}
+
 void wl1251_tx_work(struct work_struct *work);
 void wl1251_tx_complete(struct wl1251 *wl);
 void wl1251_tx_flush(struct wl1251 *wl);


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/12] wl1251: implement wl1251_acx_tid_cfg()
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (7 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 08/12] wl1251: implement acx_ac_cfg to configure hardware queues Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 10/12] wl1251: implement WMM Kalle Valo
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Needed for WMM.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Reviewed-by: Janne Ylalehto <janne.ylalehto@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_acx.c  |   36 +++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_acx.h  |   55 +++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl1251_main.c |   11 ++++++
 3 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index b409c75..beff084 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -1009,3 +1009,39 @@ out:
 	kfree(acx);
 	return ret;
 }
+
+int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
+		       enum wl1251_acx_channel_type type,
+		       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
+		       enum wl1251_acx_ack_policy ack_policy)
+{
+	struct wl1251_acx_tid_cfg *acx;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_ACX, "acx tid cfg %d type %d tsid %d "
+		     "ps_scheme %d ack_policy %d", queue, type, tsid,
+		     ps_scheme, ack_policy);
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->queue = queue;
+	acx->type = type;
+	acx->tsid = tsid;
+	acx->ps_scheme = ps_scheme;
+	acx->ack_policy = ack_policy;
+
+	ret = wl1251_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("acx tid cfg failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
index 5679324..26160c4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.h
@@ -1196,6 +1196,57 @@ struct wl1251_acx_ac_cfg {
 	u16 txop_limit;
 } __attribute__ ((packed));
 
+
+enum wl1251_acx_channel_type {
+	CHANNEL_TYPE_DCF	= 0,
+	CHANNEL_TYPE_EDCF	= 1,
+	CHANNEL_TYPE_HCCA	= 2,
+};
+
+enum wl1251_acx_ps_scheme {
+	/* regular ps: simple sending of packets */
+	WL1251_ACX_PS_SCHEME_LEGACY	= 0,
+
+	/* sending a packet triggers a unscheduled apsd downstream */
+	WL1251_ACX_PS_SCHEME_UPSD_TRIGGER	= 1,
+
+	/* a pspoll packet will be sent before every data packet */
+	WL1251_ACX_PS_SCHEME_LEGACY_PSPOLL	= 2,
+
+	/* scheduled apsd mode */
+	WL1251_ACX_PS_SCHEME_SAPSD		= 3,
+};
+
+enum wl1251_acx_ack_policy {
+	WL1251_ACX_ACK_POLICY_LEGACY	= 0,
+	WL1251_ACX_ACK_POLICY_NO_ACK	= 1,
+	WL1251_ACX_ACK_POLICY_BLOCK	= 2,
+};
+
+struct wl1251_acx_tid_cfg {
+	struct acx_header header;
+
+	/* tx queue id number (0-7) */
+	u8 queue;
+
+	/* channel access type for the queue, enum wl1251_acx_channel_type */
+	u8 type;
+
+	/* EDCA: ac index (0-3), HCCA: traffic stream id (8-15) */
+	u8 tsid;
+
+	/* ps scheme of the specified queue, enum wl1251_acx_ps_scheme */
+	u8 ps_scheme;
+
+	/* the tx queue ack policy, enum wl1251_acx_ack_policy */
+	u8 ack_policy;
+
+	u8 padding[3];
+
+	/* not supported */
+	u32 apsdconf[2];
+} __attribute__ ((packed));
+
 /*************************************************************************
 
     Host Interrupt Register (WiLink -> Host)
@@ -1354,5 +1405,9 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl);
 int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim);
 int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
 		      u8 aifs, u16 txop);
+int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
+		       enum wl1251_acx_channel_type type,
+		       u8 tsid, enum wl1251_acx_ps_scheme ps_scheme,
+		       enum wl1251_acx_ack_policy ack_policy);
 
 #endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 4d335d6..253706c 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1296,7 +1296,18 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
 	ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
 				params->cw_min, params->cw_max,
 				params->aifs, params->txop);
+	if (ret < 0)
+		goto out_sleep;
+
+	ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
+				 CHANNEL_TYPE_DCF,
+				 wl1251_tx_get_queue(queue),
+				 WL1251_ACX_PS_SCHEME_LEGACY,
+				 WL1251_ACX_ACK_POLICY_LEGACY);
+	if (ret < 0)
+		goto out_sleep;
 
+out_sleep:
 	wl1251_ps_elp_sleep(wl);
 
 out:


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/12] wl1251: implement WMM
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (8 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 09/12] wl1251: implement wl1251_acx_tid_cfg() Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 11/12] wl1251: update tx_hdr when aliging skb in tx Kalle Valo
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Now that necessary commands for WMM are implemented, implement queue handling
for WMM. But WMM is not enabled yet, only one queue is used.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Reviewed-by: Janne Ylalehto <janne.ylalehto@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_main.c |    2 +-
 drivers/net/wireless/wl12xx/wl1251_tx.c   |    8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 253706c..e1c4dd3 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1300,7 +1300,7 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
 		goto out_sleep;
 
 	ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
-				 CHANNEL_TYPE_DCF,
+				 CHANNEL_TYPE_EDCF,
 				 wl1251_tx_get_queue(queue),
 				 WL1251_ACX_PS_SCHEME_LEGACY,
 				 WL1251_ACX_ACK_POLICY_LEGACY);
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index f859706..faa23ef 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -167,8 +167,7 @@ static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
 	tx_hdr->expiry_time = cpu_to_le32(1 << 16);
 	tx_hdr->id = id;
 
-	/* FIXME: how to get the correct queue id? */
-	tx_hdr->xmit_queue = 0;
+	tx_hdr->xmit_queue = wl1251_tx_get_queue(skb_get_queue_mapping(skb));
 
 	wl1251_tx_control(tx_hdr, control, fc);
 	wl1251_tx_frag_block_num(tx_hdr);
@@ -237,8 +236,9 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
 
 	wl1251_mem_write(wl, addr, skb->data, len);
 
-	wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
-		     tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
+	wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x "
+		     "queue %d", tx_hdr->id, skb, tx_hdr->length,
+		     tx_hdr->rate, tx_hdr->xmit_queue);
 
 	return 0;
 }


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/12] wl1251: update tx_hdr when aliging skb in tx
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (9 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 10/12] wl1251: implement WMM Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-26 15:09 ` [PATCH 12/12] wl1251: enable WMM Kalle Valo
  2009-11-27 13:30 ` [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Before transmission when aligning the buffer to 4-byte bounday, tx_hdr
needs to be updated. Otherwise debug logs print false data.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_tx.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
index faa23ef..c822318 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -219,6 +219,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
 			/* align the buffer on a 4-byte boundary */
 			skb_reserve(skb, offset);
 			memmove(skb->data, src, skb->len);
+			tx_hdr = (struct tx_double_buffer_desc *) skb->data;
 		} else {
 			wl1251_info("No handler, fixme!");
 			return -EINVAL;


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 12/12] wl1251: enable WMM
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (10 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 11/12] wl1251: update tx_hdr when aliging skb in tx Kalle Valo
@ 2009-11-26 15:09 ` Kalle Valo
  2009-11-27 13:30 ` [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:09 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

From: Kalle Valo <kalle.valo@nokia.com>

Everything is ready now and we can enable WMM in mac80211.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
 drivers/net/wireless/wl12xx/wl1251_main.c |    2 ++
 drivers/net/wireless/wl12xx/wl1251_tx.h   |    3 ---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index e1c4dd3..6aeffbe 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1382,6 +1382,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
 	wl->hw->wiphy->max_scan_ssids = 1;
 	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
 
+	wl->hw->queues = 4;
+
 	ret = wl1251_register_hw(wl);
 	if (ret)
 		goto out;
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
index b7bead8..55856c6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -212,9 +212,6 @@ struct tx_result {
 
 static inline int wl1251_tx_get_queue(int queue)
 {
-	/* FIXME: use best effort until WMM is enabled */
-	return QOS_AC_BE;
-
 	switch (queue) {
 	case 0:
 		return QOS_AC_VO;


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 06/12] wl1251: fix payload alignment
  2009-11-26 15:09 ` [PATCH 06/12] wl1251: fix payload alignment Kalle Valo
@ 2009-11-26 15:13   ` Kalle Valo
  2009-11-26 18:13     ` Johannes Berg
  0 siblings, 1 reply; 19+ messages in thread
From: Kalle Valo @ 2009-11-26 15:13 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

Kalle Valo <kalle.valo@iki.fi> writes:

> mac80211 complained that in some cases IP payload was not aligned, this
> happens if the 802.11 header is not aligned with four. In that case we have
> to move entire packet to make the payload properly aligned.

[...]

> +	if (ieee80211_hdrlen(*fc) & 0x3) {
> +		from = skb->data;
> +		to = skb_push(skb, 2);
> +		memmove(to, from, skb->len);
> +		fc = (u16 *) skb->data;
> +	}

I would like to get comments about this. Is memmove() the right way to
do this?

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 06/12] wl1251: fix payload alignment
  2009-11-26 15:13   ` Kalle Valo
@ 2009-11-26 18:13     ` Johannes Berg
  2009-11-27 11:08       ` Kalle Valo
  0 siblings, 1 reply; 19+ messages in thread
From: Johannes Berg @ 2009-11-26 18:13 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, linville

[-- Attachment #1: Type: text/plain, Size: 928 bytes --]

On Thu, 2009-11-26 at 17:13 +0200, Kalle Valo wrote:
> Kalle Valo <kalle.valo@iki.fi> writes:
> 
> > mac80211 complained that in some cases IP payload was not aligned, this
> > happens if the 802.11 header is not aligned with four. In that case we have
> > to move entire packet to make the payload properly aligned.

Eh, turn off the debugging option ...

> > +	if (ieee80211_hdrlen(*fc) & 0x3) {
> > +		from = skb->data;
> > +		to = skb_push(skb, 2);
> > +		memmove(to, from, skb->len);
> > +		fc = (u16 *) skb->data;
> > +	}
> 
> I would like to get comments about this. Is memmove() the right way to
> do this?

mac80211 takes care of this for you, after warning :)

The point of the warning is to make developers aware that alignment by
firmware will be better. If you can't put the packet into the right
place directly from the device, don't bother, the memmove is done by
mac80211.

johannes


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 06/12] wl1251: fix payload alignment
  2009-11-26 18:13     ` Johannes Berg
@ 2009-11-27 11:08       ` Kalle Valo
  2009-11-27 11:11         ` Johannes Berg
  0 siblings, 1 reply; 19+ messages in thread
From: Kalle Valo @ 2009-11-27 11:08 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linville

Johannes Berg <johannes@sipsolutions.net> writes:

> On Thu, 2009-11-26 at 17:13 +0200, Kalle Valo wrote:
>> Kalle Valo <kalle.valo@iki.fi> writes:
>> 
>> > mac80211 complained that in some cases IP payload was not aligned, this
>> > happens if the 802.11 header is not aligned with four. In that case we have
>> > to move entire packet to make the payload properly aligned.
>
> Eh, turn off the debugging option ...

Sure. But isn't this warning going to create false alarms for others?

>> > +	if (ieee80211_hdrlen(*fc) & 0x3) {
>> > +		from = skb->data;
>> > +		to = skb_push(skb, 2);
>> > +		memmove(to, from, skb->len);
>> > +		fc = (u16 *) skb->data;
>> > +	}
>> 
>> I would like to get comments about this. Is memmove() the right way to
>> do this?
>
> mac80211 takes care of this for you, after warning :)

Damn, I missed that :)

> The point of the warning is to make developers aware that alignment by
> firmware will be better. If you can't put the packet into the right
> place directly from the device, don't bother, the memmove is done by
> mac80211.

Ok, I have totally misunderstood the warning then. What's the proper
way to fix this? I'll try to improve the comments in mac80211 to make
this more clear.

At least in wl1251 we have to transfer the frame to an address aligned
with four, otherwise DMA won't work. So the only solution I can think
of is that firmware adds two bytes of padding before the frame in case
of unaligned payload. Is there any other way?

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 06/12] wl1251: fix payload alignment
  2009-11-27 11:08       ` Kalle Valo
@ 2009-11-27 11:11         ` Johannes Berg
  2009-11-27 11:32           ` Kalle Valo
  0 siblings, 1 reply; 19+ messages in thread
From: Johannes Berg @ 2009-11-27 11:11 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, linville

[-- Attachment #1: Type: text/plain, Size: 1884 bytes --]

On Fri, 2009-11-27 at 13:08 +0200, Kalle Valo wrote:
> Johannes Berg <johannes@sipsolutions.net> writes:
> 
> > On Thu, 2009-11-26 at 17:13 +0200, Kalle Valo wrote:
> >> Kalle Valo <kalle.valo@iki.fi> writes:
> >> 
> >> > mac80211 complained that in some cases IP payload was not aligned, this
> >> > happens if the 802.11 header is not aligned with four. In that case we have
> >> > to move entire packet to make the payload properly aligned.
> >
> > Eh, turn off the debugging option ...
> 
> Sure. But isn't this warning going to create false alarms for others?

That's why it says "Say N unless you're writing a mac80211 based
driver." Maybe it should say "Say N unless you want to debug potential
alignment issues with your driver." Or maybe it should just go away now
that we align things properly in mac80211, and most firmware either
handles it or not, and there's nothing we can do about the firmware most
of the time... And mesh makes it more complex anyway than the warning
checks.

> > The point of the warning is to make developers aware that alignment by
> > firmware will be better. If you can't put the packet into the right
> > place directly from the device, don't bother, the memmove is done by
> > mac80211.
> 
> Ok, I have totally misunderstood the warning then. What's the proper
> way to fix this? I'll try to improve the comments in mac80211 to make
> this more clear.
> 
> At least in wl1251 we have to transfer the frame to an address aligned
> with four, otherwise DMA won't work. So the only solution I can think
> of is that firmware adds two bytes of padding before the frame in case
> of unaligned payload. Is there any other way?

No, there's no other way :) In fact, the padding has to be dynamic --
depending on whether you have QoS and/or 4addr format -- you need
padding if (!(qos ^ 4addr)) IIRC.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 06/12] wl1251: fix payload alignment
  2009-11-27 11:11         ` Johannes Berg
@ 2009-11-27 11:32           ` Kalle Valo
  0 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-27 11:32 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, linville

Johannes Berg <johannes@sipsolutions.net> writes:

> On Fri, 2009-11-27 at 13:08 +0200, Kalle Valo wrote:
>> Johannes Berg <johannes@sipsolutions.net> writes:
>> 
>> > Eh, turn off the debugging option ...
>> 
>> Sure. But isn't this warning going to create false alarms for others?
>
> That's why it says "Say N unless you're writing a mac80211 based
> driver."

I was "writing a mac80211 based driver" so I enabled it, and it
tricked me =)

> Maybe it should say "Say N unless you want to debug potential
> alignment issues with your driver." Or maybe it should just go away
> now that we align things properly in mac80211, and most firmware
> either handles it or not, and there's nothing we can do about the
> firmware most of the time... And mesh makes it more complex anyway
> than the warning checks.

Maybe we should just remove it. Like you just said, there isn't much
we can do. I'll come up with a patch unless I get objections.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 00/12] wl1251 WMM support and minor fixes
  2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
                   ` (11 preceding siblings ...)
  2009-11-26 15:09 ` [PATCH 12/12] wl1251: enable WMM Kalle Valo
@ 2009-11-27 13:30 ` Kalle Valo
  12 siblings, 0 replies; 19+ messages in thread
From: Kalle Valo @ 2009-11-27 13:30 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless

Kalle Valo <kalle.valo@iki.fi> writes:

Hi John,

> here are few patches for wl1251. Now there is WMM support and also some
> minor fixes. The patchset applies on top of the wl1251 power save fixes I
> sent earlier today.

Please drop this patch set. I have to resend it again without patch 6
(the unnecessary unaligned memmove Johannes pointed out).

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-11-27 13:29 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-26 15:08 [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo
2009-11-26 15:08 ` [PATCH 01/12] wl1251: add tx queue status to debugfs Kalle Valo
2009-11-26 15:08 ` [PATCH 02/12] wl1251: print a debug message when tx_queue is full Kalle Valo
2009-11-26 15:08 ` [PATCH 03/12] wl1251: fix error handling in wl1251_op_config() Kalle Valo
2009-11-26 15:08 ` [PATCH 04/12] wl1251: reduce ELP wakeup timeout Kalle Valo
2009-11-26 15:08 ` [PATCH 05/12] wl1251: simplify ELP wakeup time calculation Kalle Valo
2009-11-26 15:09 ` [PATCH 06/12] wl1251: fix payload alignment Kalle Valo
2009-11-26 15:13   ` Kalle Valo
2009-11-26 18:13     ` Johannes Berg
2009-11-27 11:08       ` Kalle Valo
2009-11-27 11:11         ` Johannes Berg
2009-11-27 11:32           ` Kalle Valo
2009-11-26 15:09 ` [PATCH 07/12] wl1251: use __dev_alloc_skb() on RX Kalle Valo
2009-11-26 15:09 ` [PATCH 08/12] wl1251: implement acx_ac_cfg to configure hardware queues Kalle Valo
2009-11-26 15:09 ` [PATCH 09/12] wl1251: implement wl1251_acx_tid_cfg() Kalle Valo
2009-11-26 15:09 ` [PATCH 10/12] wl1251: implement WMM Kalle Valo
2009-11-26 15:09 ` [PATCH 11/12] wl1251: update tx_hdr when aliging skb in tx Kalle Valo
2009-11-26 15:09 ` [PATCH 12/12] wl1251: enable WMM Kalle Valo
2009-11-27 13:30 ` [PATCH 00/12] wl1251 WMM support and minor fixes Kalle Valo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).