* [RFC PATCH v5 0/7] mac80211 client U-APSD support
@ 2009-12-31 13:37 Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 1/7] mac80211: add U-APSD client support Kalle Valo
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
Hello,
here is my proposal how to add U-APSD client support to mac80211. I
also included example driver implementation for wl1251.
Please comment. Also I would like to get comments how U-APSD needs to
be implemented in different hardware.
v5:
o rename IEEE80211_HW_UAPSD to IEEE80211_HW_SUPPORTS_UAPSD
o U-APSD queue and max SP length configuration debugfs interface
(requested by Jason)
o dynamic ps support for U-APSD
o by default enable U-APSD in all queues
o back to RFC state due to new code
o add a warning if both PS_NULLFUNC_STACK and U-APSD are enabled
o wl1251: set qos null data template
o more defines to ieee80211.h
v4:
o use IEEE80211_WMM_IE_STA_QOSINFO prefix in ieee80211.h (Jason Young)
o fix VI and BK qosinfo values in ieee80211.h (Jason Young)
o add IEEE80211_WMM_IE_AP_QOSINFO_UAPSD
v3:
o remove unnecessary debugfs interface, people can recompile mac80211
in case they want to try enable more queues
o add max SP length defines to ieee80211.h
o removed unnecessary code comments
v2:
o remove cfg80211 changes
o rename IEEE80211_QOS_IE to IEEE80211_WMM_IE_STA in ieee80211.h
---
Kalle Valo (7):
mac80211: add U-APSD client support
mac80211: add debugfs interface for U-APSD queue configuration
mac80211: create tx handler for dynamic ps
mac80211: check uapsd state for dynamic power save
ieee80211: add struct ieee80211_hdr_qos
wl1251: create qos null data template
wl1251: add U-APSD support
drivers/net/wireless/wl12xx/wl1251_main.c | 37 +++++++++-
include/linux/ieee80211.h | 27 +++++++
include/net/mac80211.h | 7 ++
net/mac80211/cfg.c | 7 ++
net/mac80211/debugfs.c | 94 ++++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 24 ++++++-
net/mac80211/main.c | 6 ++
net/mac80211/mlme.c | 31 ++++++++
net/mac80211/scan.c | 18 +++++
net/mac80211/tx.c | 106 ++++++++++++++++++-----------
net/mac80211/util.c | 2 +
net/mac80211/work.c | 11 ++-
12 files changed, 321 insertions(+), 49 deletions(-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH v5 1/7] mac80211: add U-APSD client support
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration Kalle Valo
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
Add Unscheduled Automatic Power-Save Delivery (U-APSD) client support. The
idea is that the data frames from the client trigger AP to send the buffered
frames with ACs which have U-APSD enabled. This decreases latency and makes it
possible to save even more power.
Driver needs to use IEEE80211_HW_UAPSD to enable the feature. The current
implementation assumes that firmware takes care of the wakeup and
hardware needing IEEE80211_HW_PS_NULLFUNC_STACK is not yet supported.
Tested with wl1251 on a Nokia N900 and Cisco Aironet 1231G AP and running
various test traffic with ping.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
include/linux/ieee80211.h | 17 +++++++++++++++++
include/net/mac80211.h | 7 +++++++
net/mac80211/cfg.c | 7 +++++++
net/mac80211/ieee80211_i.h | 10 +++++++++-
net/mac80211/main.c | 4 ++++
net/mac80211/mlme.c | 31 ++++++++++++++++++++++++++++---
net/mac80211/scan.c | 18 ++++++++++++++++++
net/mac80211/util.c | 2 ++
net/mac80211/work.c | 11 +++++++++--
9 files changed, 101 insertions(+), 6 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index aeea282..27eb5dc 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -120,6 +120,23 @@
#define IEEE80211_QOS_CTL_TID_MASK 0x000F
#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
+/* U-APSD queue for WMM IEs sent by AP */
+#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
+
+/* U-APSD queues for WMM IEs sent by STA */
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI (1<<1)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK (1<<2)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE (1<<3)
+#define IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK 0xf
+
+/* U-APSD max SP length for WMM IEs sent by STA */
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL (0<<5)
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_2 (1<<5)
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_4 (2<<5)
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_6 (3<<5)
+#define IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK (3<<5)
+
struct ieee80211_hdr {
__le16 frame_control;
__le16 duration_id;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f073a2a..f27cb4d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -113,6 +113,7 @@ struct ieee80211_tx_queue_params {
u16 cw_min;
u16 cw_max;
u8 aifs;
+ bool uapsd;
};
/**
@@ -933,6 +934,11 @@ enum ieee80211_tkip_key_type {
* Hardware supports dynamic spatial multiplexing powersave,
* ie. can turn off all but one chain and then wake the rest
* up as required after, for example, rts/cts handshake.
+ *
+ * @IEEE80211_HW_SUPPORTS_UAPSD:
+ * Hardware supports Unscheduled Automatic Power Save Delivery
+ * (U-APSD) in managed mode. The mode is configured with
+ * conf_tx() operation.
*/
enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -952,6 +958,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_BEACON_FILTER = 1<<14,
IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15,
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
+ IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2e5e841..0a432c4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1128,6 +1128,13 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
p.cw_max = params->cwmax;
p.cw_min = params->cwmin;
p.txop = params->txop;
+
+ /*
+ * Setting tx queue params disables u-apsd because it's only
+ * called in master mode.
+ */
+ p.uapsd = false;
+
if (drv_conf_tx(local, params->queue, &p)) {
printk(KERN_DEBUG "%s: failed to set TX queue "
"parameters for queue %d\n",
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a27921e..c99eeb3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -58,6 +58,12 @@ struct ieee80211_local;
#define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024))
+#define IEEE80211_DEFAULT_UAPSD_QUEUES \
+ (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \
+ IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
+ IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \
+ IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+
struct ieee80211_fragment_entry {
unsigned long first_frag_time;
unsigned int seq;
@@ -78,6 +84,7 @@ struct ieee80211_bss {
u8 dtim_period;
bool wmm_used;
+ bool uapsd_supported;
unsigned long last_probe_resp;
@@ -285,7 +292,7 @@ struct ieee80211_work {
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 ssid_len;
u8 supp_rates_len;
- bool wmm_used, use_11n;
+ bool wmm_used, use_11n, uapsd_used;
} assoc;
struct {
u32 duration;
@@ -306,6 +313,7 @@ enum ieee80211_sta_flags {
IEEE80211_STA_DISABLE_11N = BIT(4),
IEEE80211_STA_CSA_RECEIVED = BIT(5),
IEEE80211_STA_MFP_ENABLED = BIT(6),
+ IEEE80211_STA_UAPSD_ENABLED = BIT(7),
};
struct ieee80211_if_managed {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d0a14d9..5dbe06b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -492,6 +492,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+ WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)
+ && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK),
+ "U-APSD not supported with HW_PS_NULLFUNC_STACK\n");
+
/*
* Calculate scan IE length -- we need this to alloc
* memory and to subtract from the driver limit. It
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 72920ee..d1447ca 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -567,7 +567,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
struct ieee80211_tx_queue_params params;
size_t left;
int count;
- u8 *pos;
+ u8 *pos, uapsd_queues = 0;
if (local->hw.queues < 4)
return;
@@ -577,6 +577,10 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
return;
+
+ if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
+ uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
+
count = wmm_param[6] & 0x0f;
if (count == ifmgd->wmm_last_param_set)
return;
@@ -591,6 +595,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
for (; left >= 4; left -= 4, pos += 4) {
int aci = (pos[0] >> 5) & 0x03;
int acm = (pos[0] >> 4) & 0x01;
+ bool uapsd = false;
int queue;
switch (aci) {
@@ -598,22 +603,30 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
queue = 3;
if (acm)
local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
+ uapsd = true;
break;
case 2: /* AC_VI */
queue = 1;
if (acm)
local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
+ uapsd = true;
break;
case 3: /* AC_VO */
queue = 0;
if (acm)
local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+ uapsd = true;
break;
case 0: /* AC_BE */
default:
queue = 2;
if (acm)
local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
+ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
+ uapsd = true;
break;
}
@@ -621,11 +634,14 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
params.cw_min = ecw2cw(pos[1] & 0x0f);
params.txop = get_unaligned_le16(pos + 2);
+ params.uapsd = uapsd;
+
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
- "cWmin=%d cWmax=%d txop=%d\n",
+ "cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
wiphy_name(local->hw.wiphy), queue, aci, acm,
- params.aifs, params.cw_min, params.cw_max, params.txop);
+ params.aifs, params.cw_min, params.cw_max, params.txop,
+ params.uapsd);
#endif
if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx)
printk(KERN_DEBUG "%s: failed to set TX queue "
@@ -1897,6 +1913,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
wk->assoc.ht_information_ie =
ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
+ if (bss->wmm_used && bss->uapsd_supported &&
+ (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
+ wk->assoc.uapsd_used = true;
+ ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
+ } else {
+ wk->assoc.uapsd_used = false;
+ ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
+ }
+
ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
memcpy(wk->assoc.ssid, ssid + 2, ssid[1]);
wk->assoc.ssid_len = ssid[1];
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 365f409..4a70719 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -55,6 +55,23 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv));
}
+static bool is_uapsd_supported(struct ieee802_11_elems *elems)
+{
+ u8 qos_info;
+
+ if (elems->wmm_info && elems->wmm_info_len == 7
+ && elems->wmm_info[5] == 1)
+ qos_info = elems->wmm_info[6];
+ else if (elems->wmm_param && elems->wmm_param_len == 24
+ && elems->wmm_param[5] == 1)
+ qos_info = elems->wmm_param[6];
+ else
+ /* no valid wmm information or parameter element found */
+ return false;
+
+ return qos_info & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD;
+}
+
struct ieee80211_bss *
ieee80211_bss_info_update(struct ieee80211_local *local,
struct ieee80211_rx_status *rx_status,
@@ -118,6 +135,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
}
bss->wmm_used = elems->wmm_param || elems->wmm_info;
+ bss->uapsd_supported = is_uapsd_supported(elems);
if (!beacon)
bss->last_probe_resp = jiffies;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7e38858..5e7491b 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -781,6 +781,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
break;
}
+ qparam.uapsd = false;
+
drv_conf_tx(local, queue, &qparam);
}
}
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 5ba7599..4bbf9ab 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -202,7 +202,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
- u8 *pos;
+ u8 *pos, qos_info;
const u8 *ies;
size_t offset = 0, noffset;
int i, len, count, rates_len, supp_rates_len;
@@ -375,6 +375,13 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
}
if (wk->assoc.wmm_used && local->hw.queues >= 4) {
+ if (wk->assoc.uapsd_used) {
+ qos_info = IEEE80211_DEFAULT_UAPSD_QUEUES;
+ qos_info |= IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
+ } else {
+ qos_info = 0;
+ }
+
pos = skb_put(skb, 9);
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
*pos++ = 7; /* len */
@@ -384,7 +391,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
*pos++ = 2; /* WME */
*pos++ = 0; /* WME info */
*pos++ = 1; /* WME ver */
- *pos++ = 0;
+ *pos++ = qos_info;
}
/* add any remaining custom (i.e. vendor specific here) IEs */
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 1/7] mac80211: add U-APSD client support Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2010-01-05 9:48 ` Johannes Berg
2009-12-31 13:37 ` [RFC PATCH v5 3/7] mac80211: create tx handler for dynamic ps Kalle Valo
` (5 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
Because it's not yet decided how to configure which queues are U-APSD
enabled, add a debugfs interface for testing purposes.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
net/mac80211/debugfs.c | 94 ++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 14 +++++++
net/mac80211/main.c | 2 +
net/mac80211/mlme.c | 2 -
net/mac80211/work.c | 4 +-
5 files changed, 113 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index e4b5409..8b9a9d4 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -158,6 +158,98 @@ static const struct file_operations noack_ops = {
.open = mac80211_open_file_generic
};
+static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ int res;
+ char buf[10];
+
+ res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static ssize_t uapsd_queues_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ unsigned long val;
+ char buf[10];
+ size_t len;
+ int ret;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ ret = strict_strtoul(buf, 0, &val);
+
+ if (ret)
+ return -EINVAL;
+
+ if (val != 0 && (val & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) == 0)
+ return -ERANGE;
+
+ local->uapsd_queues = val;
+
+ return count;
+}
+
+static const struct file_operations uapsd_queues_ops = {
+ .read = uapsd_queues_read,
+ .write = uapsd_queues_write,
+ .open = mac80211_open_file_generic
+};
+
+static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ int res;
+ char buf[10];
+
+ res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static ssize_t uapsd_max_sp_len_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ unsigned long val;
+ char buf[10];
+ size_t len;
+ int ret;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+
+ ret = strict_strtoul(buf, 0, &val);
+
+ if (ret)
+ return -EINVAL;
+
+ if (val != 0 && (val & IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) == 0)
+ return -ERANGE;
+
+ local->uapsd_max_sp_len = val;
+
+ return count;
+}
+
+static const struct file_operations uapsd_max_sp_len_ops = {
+ .read = uapsd_max_sp_len_read,
+ .write = uapsd_max_sp_len_write,
+ .open = mac80211_open_file_generic
+};
+
static ssize_t queues_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -314,6 +406,8 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_ADD(queues);
DEBUGFS_ADD_MODE(reset, 0200);
DEBUGFS_ADD(noack);
+ DEBUGFS_ADD(uapsd_queues);
+ DEBUGFS_ADD(uapsd_max_sp_len);
statsd = debugfs_create_dir("statistics", phyd);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c99eeb3..c6b7c92 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -805,6 +805,20 @@ struct ieee80211_local {
int wifi_wme_noack_test;
unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
+ /*
+ * Bitmask of enabled u-apsd queues,
+ * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association
+ * to take effect.
+ */
+ unsigned int uapsd_queues;
+
+ /*
+ * Maximum number of buffered frames AP can deliver during a
+ * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar.
+ * Needs a new association to take effect.
+ */
+ unsigned int uapsd_max_sp_len;
+
bool pspolling;
bool offchannel_ps_enabled;
/*
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5dbe06b..f8ca2ce 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -385,6 +385,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
local->user_power_level = -1;
+ local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
+ local->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
INIT_LIST_HEAD(&local->interfaces);
mutex_init(&local->iflist_mtx);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d1447ca..41cfe59 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -579,7 +579,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
return;
if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
- uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
+ uapsd_queues = local->uapsd_queues;
count = wmm_param[6] & 0x0f;
if (count == ifmgd->wmm_last_param_set)
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 4bbf9ab..d1e738c 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -376,8 +376,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
if (wk->assoc.wmm_used && local->hw.queues >= 4) {
if (wk->assoc.uapsd_used) {
- qos_info = IEEE80211_DEFAULT_UAPSD_QUEUES;
- qos_info |= IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
+ qos_info = local->uapsd_queues;
+ qos_info |= local->uapsd_max_sp_len;
} else {
qos_info = 0;
}
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v5 3/7] mac80211: create tx handler for dynamic ps
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 1/7] mac80211: add U-APSD client support Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 4/7] mac80211: check uapsd state for dynamic power save Kalle Valo
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
Currently dynamic ps check is in ieee80211_xmit(), but it's cleaner
to have a separate tx handler for this. Also this is a prerequisite for
U-APSD client mode which needs to know the queue frame is in.
Also need_dynamic_ps() function is embedded to the tx handler.
No functional changes expect that the code is run in a later phase than
originally.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
net/mac80211/tx.c | 81 +++++++++++++++++++++++++++--------------------------
1 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7bba49d..32bbbc2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -180,6 +180,46 @@ static int inline is_ieee80211_device(struct ieee80211_local *local,
}
/* tx handlers */
+static ieee80211_tx_result debug_noinline
+ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
+{
+ struct ieee80211_local *local = tx->local;
+
+ /* driver doesn't support power save */
+ if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
+ return TX_CONTINUE;
+
+ /* hardware does dynamic power save */
+ if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
+ return TX_CONTINUE;
+
+ /* dynamic power save disabled */
+ if (local->hw.conf.dynamic_ps_timeout <= 0)
+ return TX_CONTINUE;
+
+ /* we are scanning, don't enable power save */
+ if (local->scanning)
+ return TX_CONTINUE;
+
+ if (!local->ps_sdata)
+ return TX_CONTINUE;
+
+ /* No point if we're going to suspend */
+ if (local->quiescing)
+ return TX_CONTINUE;
+
+ if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+ ieee80211_stop_queues_by_reason(&local->hw,
+ IEEE80211_QUEUE_STOP_REASON_PS);
+ ieee80211_queue_work(&local->hw,
+ &local->dynamic_ps_disable_work);
+ }
+
+ mod_timer(&local->dynamic_ps_timer, jiffies +
+ msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
+
+ return TX_CONTINUE;
+}
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
@@ -1215,6 +1255,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
goto txh_done; \
} while (0)
+ CALL_TXH(ieee80211_tx_h_dynamic_ps);
CALL_TXH(ieee80211_tx_h_check_assoc);
CALL_TXH(ieee80211_tx_h_ps_buf);
CALL_TXH(ieee80211_tx_h_select_key);
@@ -1397,34 +1438,6 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
return 0;
}
-static bool need_dynamic_ps(struct ieee80211_local *local)
-{
- /* driver doesn't support power save */
- if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
- return false;
-
- /* hardware does dynamic power save */
- if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
- return false;
-
- /* dynamic power save disabled */
- if (local->hw.conf.dynamic_ps_timeout <= 0)
- return false;
-
- /* we are scanning, don't enable power save */
- if (local->scanning)
- return false;
-
- if (!local->ps_sdata)
- return false;
-
- /* No point if we're going to suspend */
- if (local->quiescing)
- return false;
-
- return true;
-}
-
static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
@@ -1435,18 +1448,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
int headroom;
bool may_encrypt;
- if (need_dynamic_ps(local)) {
- if (local->hw.conf.flags & IEEE80211_CONF_PS) {
- ieee80211_stop_queues_by_reason(&local->hw,
- IEEE80211_QUEUE_STOP_REASON_PS);
- ieee80211_queue_work(&local->hw,
- &local->dynamic_ps_disable_work);
- }
-
- mod_timer(&local->dynamic_ps_timer, jiffies +
- msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
- }
-
rcu_read_lock();
if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v5 4/7] mac80211: check uapsd state for dynamic power save
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
` (2 preceding siblings ...)
2009-12-31 13:37 ` [RFC PATCH v5 3/7] mac80211: create tx handler for dynamic ps Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 5/7] ieee80211: add struct ieee80211_hdr_qos Kalle Valo
` (3 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
To make U-APSD client mode effective, we must not wake up from dynamic power
save when transmitting frames. So if dynamic power save is enabled, it needs
check the queue the transmitted packet is in and decide if we need to wake
up or not.
In a perfect world, where all packets would have correct QoS tags, U-APSD
enabled queues should not trigger wakeup from power save. But in the real
world, where very few packets have correct QoS tags, this won't work. For
example, if only voip class has U-APSD enabled and we send a packet in voip
class, but the packets we receive are in best effort class, we would receive
the packets with the legacy power save method. And that would increase
latencies too much from a voip application point of view.
The workaround is to enable U-APSD for all qeueus and still use dynamic ps
wakeup for all other queues except voip. That way we can still save power
with a voip application and not sacrifice latency. Normal traffic (in
background, best effort or video class) would still trigger wakeup from
dynamic power save.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
net/mac80211/tx.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 32bbbc2..a782f4c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -184,6 +184,7 @@ static ieee80211_tx_result debug_noinline
ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
{
struct ieee80211_local *local = tx->local;
+ struct ieee80211_if_managed *ifmgd;
/* driver doesn't support power save */
if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -208,6 +209,30 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
if (local->quiescing)
return TX_CONTINUE;
+ /* dynamic ps is supported only in managed mode */
+ if (tx->sdata->vif.type != NL80211_IFTYPE_STATION)
+ return TX_CONTINUE;
+
+ ifmgd = &tx->sdata->u.mgd;
+
+ /*
+ * Don't wakeup from power save if u-apsd is enabled, voip ac has
+ * u-apsd enabled and the frame is in voip class. This effectively
+ * means that even if all access categories have u-apsd enabled, in
+ * practise u-apsd is only used with the voip ac. This is a
+ * workaround for the case when received voip class packets do not
+ * have correct qos tag for some reason, due the network or the
+ * peer application.
+ *
+ * Note: local->uapsd_queues access is racy here. If the value is
+ * changed via debugfs, user needs to reassociate manually to have
+ * everything in sync.
+ */
+ if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
+ && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
+ && skb_get_queue_mapping(tx->skb) == 0)
+ return TX_CONTINUE;
+
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_QUEUE_STOP_REASON_PS);
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v5 5/7] ieee80211: add struct ieee80211_hdr_qos
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
` (3 preceding siblings ...)
2009-12-31 13:37 ` [RFC PATCH v5 4/7] mac80211: check uapsd state for dynamic power save Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 6/7] wl1251: create qos null data template Kalle Valo
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
The header can be used to create qos nullfunc frames, for example.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
include/linux/ieee80211.h | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 27eb5dc..57859c4 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -147,6 +147,16 @@ struct ieee80211_hdr {
u8 addr4[6];
} __attribute__ ((packed));
+struct ieee80211_qos_hdr {
+ __le16 frame_control;
+ __le16 duration_id;
+ u8 addr1[6];
+ u8 addr2[6];
+ u8 addr3[6];
+ __le16 seq_ctrl;
+ __le16 qos_ctrl;
+} __attribute__ ((packed));
+
/**
* ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
* @fc: frame control bytes in little-endian byteorder
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v5 6/7] wl1251: create qos null data template
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
` (4 preceding siblings ...)
2009-12-31 13:37 ` [RFC PATCH v5 5/7] ieee80211: add struct ieee80211_hdr_qos Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 7/7] wl1251: add U-APSD support Kalle Valo
2010-01-05 9:51 ` [RFC PATCH v5 0/7] mac80211 client " Johannes Berg
7 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
The qos null data template is needed for U-APSD.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
drivers/net/wireless/wl12xx/wl1251_main.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 4e373f3..4cf3545 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -585,6 +585,27 @@ static int wl1251_build_null_data(struct wl1251 *wl)
}
+static int wl1251_build_qos_null_data(struct wl1251 *wl)
+{
+ struct ieee80211_qos_hdr template;
+
+ memset(&template, 0, sizeof(template));
+
+ memcpy(template.addr1, wl->bssid, ETH_ALEN);
+ memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
+ memcpy(template.addr3, wl->bssid, ETH_ALEN);
+
+ template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+ IEEE80211_STYPE_QOS_NULLFUNC |
+ IEEE80211_FCTL_TODS);
+
+ /* FIXME: not sure what priority to use here */
+ template.qos_ctrl = cpu_to_le16(0);
+
+ return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
+ sizeof(template));
+}
+
static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
{
struct wl12xx_ps_poll_template template;
@@ -1119,6 +1140,10 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
if (ret < 0)
goto out;
+ ret = wl1251_build_qos_null_data(wl);
+ if (ret < 0)
+ goto out;
+
if (wl->bss_type != BSS_TYPE_IBSS) {
ret = wl1251_join(wl, wl->bss_type, wl->channel,
wl->beacon_int, wl->dtim_period);
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v5 7/7] wl1251: add U-APSD support
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
` (5 preceding siblings ...)
2009-12-31 13:37 ` [RFC PATCH v5 6/7] wl1251: create qos null data template Kalle Valo
@ 2009-12-31 13:37 ` Kalle Valo
2010-01-05 9:51 ` [RFC PATCH v5 0/7] mac80211 client " Johannes Berg
7 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2009-12-31 13:37 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, a.young.jason
From: Kalle Valo <kalle.valo@nokia.com>
wl1251 firmware supports U-APSD just with a simple queue configuration
change so enable it.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
---
drivers/net/wireless/wl12xx/wl1251_main.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 4cf3545..6be50aa 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1307,6 +1307,7 @@ static struct ieee80211_channel wl1251_channels[] = {
static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
+ enum wl1251_acx_ps_scheme ps_scheme;
struct wl1251 *wl = hw->priv;
int ret;
@@ -1324,10 +1325,14 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
if (ret < 0)
goto out_sleep;
+ if (params->uapsd)
+ ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
+ else
+ ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
+
ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
CHANNEL_TYPE_EDCF,
- wl1251_tx_get_queue(queue),
- WL1251_ACX_PS_SCHEME_LEGACY,
+ wl1251_tx_get_queue(queue), ps_scheme,
WL1251_ACX_ACK_POLICY_LEGACY);
if (ret < 0)
goto out_sleep;
@@ -1401,7 +1406,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM |
IEEE80211_HW_SUPPORTS_PS |
- IEEE80211_HW_BEACON_FILTER;
+ IEEE80211_HW_BEACON_FILTER |
+ IEEE80211_HW_SUPPORTS_UAPSD;
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
wl->hw->wiphy->max_scan_ssids = 1;
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration
2009-12-31 13:37 ` [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration Kalle Valo
@ 2010-01-05 9:48 ` Johannes Berg
2010-01-05 10:27 ` Kalle Valo
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-01-05 9:48 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless, a.young.jason
[-- Attachment #1: Type: text/plain, Size: 1435 bytes --]
On Thu, 2009-12-31 at 15:37 +0200, Kalle Valo wrote:
> +static ssize_t uapsd_max_sp_len_read(struct file *file, char __user
> *user_buf,
> + size_t count, loff_t *ppos)
> +{
> + struct ieee80211_local *local = file->private_data;
> + int res;
> + char buf[10];
> +
> + res = scnprintf(buf, sizeof(buf), "0x%x\n",
> local->uapsd_max_sp_len);
> +
> + return simple_read_from_buffer(user_buf, count, ppos, buf, res);
> +}
> +
> +static ssize_t uapsd_max_sp_len_write(struct file *file,
> + const char __user *user_buf,
> + size_t count, loff_t *ppos)
> +{
> + struct ieee80211_local *local = file->private_data;
> + unsigned long val;
> + char buf[10];
> + size_t len;
> + int ret;
> +
> + len = min(count, sizeof(buf) - 1);
> + if (copy_from_user(buf, user_buf, len))
> + return -EFAULT;
> + buf[len] = '\0';
> +
> + ret = strict_strtoul(buf, 0, &val);
> +
> + if (ret)
> + return -EINVAL;
> +
> + if (val != 0 && (val & IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) == 0)
> + return -ERANGE;
> +
> + local->uapsd_max_sp_len = val;
This seems a bit weird, that means you need to use 0x20, ..., 0x60,
right? I think you should shift it up/down when reading/writing, or
probably even store it shifted in local->uapsd_max_sp_len and then shift
it up by 5 when using that value -- the value itself is only 0..3 after
all, and only stored in a bitmasked field.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v5 0/7] mac80211 client U-APSD support
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
` (6 preceding siblings ...)
2009-12-31 13:37 ` [RFC PATCH v5 7/7] wl1251: add U-APSD support Kalle Valo
@ 2010-01-05 9:51 ` Johannes Berg
2010-01-05 10:31 ` Kalle Valo
7 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-01-05 9:51 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless, a.young.jason
[-- Attachment #1: Type: text/plain, Size: 420 bytes --]
On Thu, 2009-12-31 at 15:37 +0200, Kalle Valo wrote:
> Hello,
>
> here is my proposal how to add U-APSD client support to mac80211. I
> also included example driver implementation for wl1251.
>
> Please comment. Also I would like to get comments how U-APSD needs to
> be implemented in different hardware.
Looks ok to me (very few comments inline), but I haven't researched
Intel hardware yet.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration
2010-01-05 9:48 ` Johannes Berg
@ 2010-01-05 10:27 ` Kalle Valo
2010-01-05 10:44 ` Johannes Berg
0 siblings, 1 reply; 14+ messages in thread
From: Kalle Valo @ 2010-01-05 10:27 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, a.young.jason
Johannes Berg <johannes@sipsolutions.net> writes:
>> + ret = strict_strtoul(buf, 0, &val);
>> +
>> + if (ret)
>> + return -EINVAL;
>> +
>> + if (val != 0 && (val & IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) == 0)
>> + return -ERANGE;
>> +
>> + local->uapsd_max_sp_len = val;
>
> This seems a bit weird, that means you need to use 0x20, ..., 0x60,
> right?
Yes.
> I think you should shift it up/down when reading/writing, or
> probably even store it shifted in local->uapsd_max_sp_len and then
> shift it up by 5 when using that value -- the value itself is only
> 0..3 after all, and only stored in a bitmasked field.
I was actually thinking this option but ended up requiring the user to
do the shift. But thinking is again it doesn't make any sense, I'll do
it as you recommend.
I'll store the values shifted in local->uapsd_max_sp_len and do the
conversion in debugfs.c.
--
Kalle Valo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v5 0/7] mac80211 client U-APSD support
2010-01-05 9:51 ` [RFC PATCH v5 0/7] mac80211 client " Johannes Berg
@ 2010-01-05 10:31 ` Kalle Valo
0 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2010-01-05 10:31 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, a.young.jason
Johannes Berg <johannes@sipsolutions.net> writes:
> On Thu, 2009-12-31 at 15:37 +0200, Kalle Valo wrote:
>> Hello,
>>
>> here is my proposal how to add U-APSD client support to mac80211. I
>> also included example driver implementation for wl1251.
>>
>> Please comment. Also I would like to get comments how U-APSD needs to
>> be implemented in different hardware.
>
> Looks ok to me (very few comments inline)
Thanks. I'll send v6 later and hopefully John can take that one. We
can improve the u-apsd implementation later on as needed.
> but I haven't researched Intel hardware yet.
I haven't looked either, but I'm hoping that the mac80211 current
implementation is enough also for Intel hardware.
--
Kalle Valo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration
2010-01-05 10:27 ` Kalle Valo
@ 2010-01-05 10:44 ` Johannes Berg
2010-01-05 10:53 ` Kalle Valo
0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-01-05 10:44 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless, a.young.jason
[-- Attachment #1: Type: text/plain, Size: 362 bytes --]
On Tue, 2010-01-05 at 12:27 +0200, Kalle Valo wrote:
> I'll store the values shifted in local->uapsd_max_sp_len and do the
> conversion in debugfs.c.
Ok, but please add a comment then to the field that it's already
shifted, typically we store values as per spec (0,1,2,3) and then put
them into the right bitmap position when using them.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration
2010-01-05 10:44 ` Johannes Berg
@ 2010-01-05 10:53 ` Kalle Valo
0 siblings, 0 replies; 14+ messages in thread
From: Kalle Valo @ 2010-01-05 10:53 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, a.young.jason
Johannes Berg <johannes@sipsolutions.net> writes:
> On Tue, 2010-01-05 at 12:27 +0200, Kalle Valo wrote:
>
>> I'll store the values shifted in local->uapsd_max_sp_len and do the
>> conversion in debugfs.c.
>
> Ok, but please add a comment then to the field that it's already
> shifted, typically we store values as per spec (0,1,2,3) and then put
> them into the right bitmap position when using them.
Oh, I didn't know that. In that case I do the shift when creating the
frame :)
Thanks again.
--
Kalle Valo
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2010-01-05 10:53 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-31 13:37 [RFC PATCH v5 0/7] mac80211 client U-APSD support Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 1/7] mac80211: add U-APSD client support Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 2/7] mac80211: add debugfs interface for U-APSD queue configuration Kalle Valo
2010-01-05 9:48 ` Johannes Berg
2010-01-05 10:27 ` Kalle Valo
2010-01-05 10:44 ` Johannes Berg
2010-01-05 10:53 ` Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 3/7] mac80211: create tx handler for dynamic ps Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 4/7] mac80211: check uapsd state for dynamic power save Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 5/7] ieee80211: add struct ieee80211_hdr_qos Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 6/7] wl1251: create qos null data template Kalle Valo
2009-12-31 13:37 ` [RFC PATCH v5 7/7] wl1251: add U-APSD support Kalle Valo
2010-01-05 9:51 ` [RFC PATCH v5 0/7] mac80211 client " Johannes Berg
2010-01-05 10:31 ` 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).