diff options
author | Kalle Valo <kalle.valo@nokia.com> | 2010-01-12 03:42:31 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-12 14:20:58 -0500 |
commit | ab13315af97919fae0e014748105fdc2e30afb2d (patch) | |
tree | befa549272ecff20b2839bd6671e4cccbce448f9 /net/mac80211/work.c | |
parent | 2d46d7c121436f1dafe91b0a8d9b99e534cfa5f8 (diff) |
mac80211: add U-APSD client support
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>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/work.c')
-rw-r--r-- | net/mac80211/work.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 7c5d95b1bc04..a74fd6ee0083 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, | |||
202 | struct ieee80211_local *local = sdata->local; | 202 | struct ieee80211_local *local = sdata->local; |
203 | struct sk_buff *skb; | 203 | struct sk_buff *skb; |
204 | struct ieee80211_mgmt *mgmt; | 204 | struct ieee80211_mgmt *mgmt; |
205 | u8 *pos; | 205 | u8 *pos, qos_info; |
206 | const u8 *ies; | 206 | const u8 *ies; |
207 | size_t offset = 0, noffset; | 207 | size_t offset = 0, noffset; |
208 | int i, len, count, rates_len, supp_rates_len; | 208 | int i, len, count, rates_len, supp_rates_len; |
@@ -375,6 +375,14 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
375 | } | 375 | } |
376 | 376 | ||
377 | if (wk->assoc.wmm_used && local->hw.queues >= 4) { | 377 | if (wk->assoc.wmm_used && local->hw.queues >= 4) { |
378 | if (wk->assoc.uapsd_used) { | ||
379 | qos_info = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
380 | qos_info |= (IEEE80211_DEFAULT_MAX_SP_LEN << | ||
381 | IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT); | ||
382 | } else { | ||
383 | qos_info = 0; | ||
384 | } | ||
385 | |||
378 | pos = skb_put(skb, 9); | 386 | pos = skb_put(skb, 9); |
379 | *pos++ = WLAN_EID_VENDOR_SPECIFIC; | 387 | *pos++ = WLAN_EID_VENDOR_SPECIFIC; |
380 | *pos++ = 7; /* len */ | 388 | *pos++ = 7; /* len */ |
@@ -384,7 +392,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
384 | *pos++ = 2; /* WME */ | 392 | *pos++ = 2; /* WME */ |
385 | *pos++ = 0; /* WME info */ | 393 | *pos++ = 0; /* WME info */ |
386 | *pos++ = 1; /* WME ver */ | 394 | *pos++ = 1; /* WME ver */ |
387 | *pos++ = 0; | 395 | *pos++ = qos_info; |
388 | } | 396 | } |
389 | 397 | ||
390 | /* add any remaining custom (i.e. vendor specific here) IEs */ | 398 | /* add any remaining custom (i.e. vendor specific here) IEs */ |