All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.