* [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).