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

Hello 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.

These patches are not urgent.

v2: dropped patch "wl1251: fix payload alignment"

---

Kalle Valo (11):
      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: 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      |    2 -
 drivers/net/wireless/wl12xx/wl1251_tx.c      |    9 +--
 drivers/net/wireless/wl12xx/wl1251_tx.h      |   17 +++++
 11 files changed, 308 insertions(+), 11 deletions(-)


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

* [PATCH v2 01/11] wl1251: add tx queue status to debugfs
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
@ 2009-11-30  8:17 ` Kalle Valo
  2009-11-30  8:17 ` [PATCH v2 02/11] wl1251: print a debug message when tx_queue is full Kalle Valo
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:17 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] 12+ messages in thread

* [PATCH v2 02/11] wl1251: print a debug message when tx_queue is full
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
  2009-11-30  8:17 ` [PATCH v2 01/11] wl1251: add tx queue status to debugfs Kalle Valo
@ 2009-11-30  8:17 ` Kalle Valo
  2009-11-30  8:17 ` [PATCH v2 03/11] wl1251: fix error handling in wl1251_op_config() Kalle Valo
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:17 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 ff4be7b..0417745 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] 12+ messages in thread

* [PATCH v2 03/11] wl1251: fix error handling in wl1251_op_config()
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
  2009-11-30  8:17 ` [PATCH v2 01/11] wl1251: add tx queue status to debugfs Kalle Valo
  2009-11-30  8:17 ` [PATCH v2 02/11] wl1251: print a debug message when tx_queue is full Kalle Valo
@ 2009-11-30  8:17 ` Kalle Valo
  2009-11-30  8:17 ` [PATCH v2 04/11] wl1251: reduce ELP wakeup timeout Kalle Valo
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:17 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 0417745..24050d5 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -645,20 +645,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] 12+ messages in thread

* [PATCH v2 04/11] wl1251: reduce ELP wakeup timeout
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (2 preceding siblings ...)
  2009-11-30  8:17 ` [PATCH v2 03/11] wl1251: fix error handling in wl1251_op_config() Kalle Valo
@ 2009-11-30  8:17 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 05/11] wl1251: simplify ELP wakeup time calculation Kalle Valo
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:17 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] 12+ messages in thread

* [PATCH v2 05/11] wl1251: simplify ELP wakeup time calculation
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (3 preceding siblings ...)
  2009-11-30  8:17 ` [PATCH v2 04/11] wl1251: reduce ELP wakeup timeout Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 06/11] wl1251: use __dev_alloc_skb() on RX Kalle Valo
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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] 12+ messages in thread

* [PATCH v2 06/11] wl1251: use __dev_alloc_skb() on RX
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (4 preceding siblings ...)
  2009-11-30  8:18 ` [PATCH v2 05/11] wl1251: simplify ELP wakeup time calculation Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 07/11] wl1251: implement acx_ac_cfg to configure hardware queues Kalle Valo
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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 f84cc89..b567322 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -126,7 +126,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);
+	skb = __dev_alloc_skb(length, GFP_KERNEL);
 	if (!skb) {
 		wl1251_error("Couldn't allocate RX frame");
 		return;


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

* [PATCH v2 07/11] wl1251: implement acx_ac_cfg to configure hardware queues
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (5 preceding siblings ...)
  2009-11-30  8:18 ` [PATCH v2 06/11] wl1251: use __dev_alloc_skb() on RX Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 08/11] wl1251: implement wl1251_acx_tid_cfg() Kalle Valo
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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 24050d5..c1c7cb5 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1285,6 +1285,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,
@@ -1305,6 +1331,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] 12+ messages in thread

* [PATCH v2 08/11] wl1251: implement wl1251_acx_tid_cfg()
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (6 preceding siblings ...)
  2009-11-30  8:18 ` [PATCH v2 07/11] wl1251: implement acx_ac_cfg to configure hardware queues Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 09/11] wl1251: implement WMM Kalle Valo
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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 c1c7cb5..74770ad 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1302,7 +1302,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] 12+ messages in thread

* [PATCH v2 09/11] wl1251: implement WMM
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (7 preceding siblings ...)
  2009-11-30  8:18 ` [PATCH v2 08/11] wl1251: implement wl1251_acx_tid_cfg() Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 10/11] wl1251: update tx_hdr when aliging skb in tx Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 11/11] wl1251: enable WMM Kalle Valo
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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 74770ad..563c84f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1306,7 +1306,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] 12+ messages in thread

* [PATCH v2 10/11] wl1251: update tx_hdr when aliging skb in tx
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (8 preceding siblings ...)
  2009-11-30  8:18 ` [PATCH v2 09/11] wl1251: implement WMM Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  2009-11-30  8:18 ` [PATCH v2 11/11] wl1251: enable WMM Kalle Valo
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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] 12+ messages in thread

* [PATCH v2 11/11] wl1251: enable WMM
  2009-11-30  8:17 [PATCH v2 00/11] wl1251 WMM support and minor fixes Kalle Valo
                   ` (9 preceding siblings ...)
  2009-11-30  8:18 ` [PATCH v2 10/11] wl1251: update tx_hdr when aliging skb in tx Kalle Valo
@ 2009-11-30  8:18 ` Kalle Valo
  10 siblings, 0 replies; 12+ messages in thread
From: Kalle Valo @ 2009-11-30  8:18 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 563c84f..63511ca 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1388,6 +1388,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] 12+ messages in thread

end of thread, other threads:[~2009-11-30  8:20 UTC | newest]

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