aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/wl12xx/acx.c5
-rw-r--r--drivers/net/wireless/wl12xx/acx.h3
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c10
-rw-r--r--drivers/net/wireless/wl12xx/event.c4
-rw-r--r--drivers/net/wireless/wl12xx/main.c53
-rw-r--r--drivers/net/wireless/wl12xx/rx.c35
-rw-r--r--drivers/net/wireless/wl12xx/tx.c67
-rw-r--r--drivers/net/wireless/wl12xx/tx.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h12
9 files changed, 109 insertions, 81 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 5b70cc19e1d4..21e74ca4ddb2 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1510,10 +1510,9 @@ out:
1510 return ret; 1510 return ret;
1511} 1511}
1512 1512
1513int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable) 1513int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1514 bool enable)
1514{ 1515{
1515 struct ieee80211_vif *vif = wl->vif; /* TODO: get as param */
1516 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
1517 struct wl1271_acx_ps_rx_streaming *rx_streaming; 1516 struct wl1271_acx_ps_rx_streaming *rx_streaming;
1518 u32 conf_queues, enable_queues; 1517 u32 conf_queues, enable_queues;
1519 int i, ret = 0; 1518 int i, ret = 0;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 7fccfcc55ca0..c06119b053e3 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1310,7 +1310,8 @@ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
1310int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, 1310int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
1311 u16 ssn, bool enable, u8 peer_hlid); 1311 u16 ssn, bool enable, u8 peer_hlid);
1312int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); 1312int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
1313int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable); 1313int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1314 bool enable);
1314int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif); 1315int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif);
1315int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif); 1316int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif);
1316int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); 1317int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 669b081848e8..4abff8274ac3 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -505,6 +505,7 @@ static ssize_t rx_streaming_interval_write(struct file *file,
505 size_t count, loff_t *ppos) 505 size_t count, loff_t *ppos)
506{ 506{
507 struct wl1271 *wl = file->private_data; 507 struct wl1271 *wl = file->private_data;
508 struct wl12xx_vif *wlvif;
508 unsigned long value; 509 unsigned long value;
509 int ret; 510 int ret;
510 511
@@ -528,7 +529,9 @@ static ssize_t rx_streaming_interval_write(struct file *file,
528 if (ret < 0) 529 if (ret < 0)
529 goto out; 530 goto out;
530 531
531 wl1271_recalc_rx_streaming(wl); 532 wl12xx_for_each_wlvif_sta(wl, wlvif) {
533 wl1271_recalc_rx_streaming(wl, wlvif);
534 }
532 535
533 wl1271_ps_elp_sleep(wl); 536 wl1271_ps_elp_sleep(wl);
534out: 537out:
@@ -557,6 +560,7 @@ static ssize_t rx_streaming_always_write(struct file *file,
557 size_t count, loff_t *ppos) 560 size_t count, loff_t *ppos)
558{ 561{
559 struct wl1271 *wl = file->private_data; 562 struct wl1271 *wl = file->private_data;
563 struct wl12xx_vif *wlvif;
560 unsigned long value; 564 unsigned long value;
561 int ret; 565 int ret;
562 566
@@ -580,7 +584,9 @@ static ssize_t rx_streaming_always_write(struct file *file,
580 if (ret < 0) 584 if (ret < 0)
581 goto out; 585 goto out;
582 586
583 wl1271_recalc_rx_streaming(wl); 587 wl12xx_for_each_wlvif_sta(wl, wlvif) {
588 wl1271_recalc_rx_streaming(wl, wlvif);
589 }
584 590
585 wl1271_ps_elp_sleep(wl); 591 wl1271_ps_elp_sleep(wl);
586out: 592out:
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index dbc40bb49bcd..be9e1121c8f8 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -220,12 +220,12 @@ static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
220 } 220 }
221 set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); 221 set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
222 } else { 222 } else {
223 clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
223 wl12xx_for_each_wlvif_sta(wl, wlvif) { 224 wl12xx_for_each_wlvif_sta(wl, wlvif) {
224 vif = wl12xx_wlvif_to_vif(wlvif); 225 vif = wl12xx_wlvif_to_vif(wlvif);
225 ieee80211_enable_dyn_ps(vif); 226 ieee80211_enable_dyn_ps(vif);
227 wl1271_recalc_rx_streaming(wl, wlvif);
226 } 228 }
227 clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags);
228 wl1271_recalc_rx_streaming(wl);
229 } 229 }
230 230
231} 231}
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 8d87df53bbec..5ce01f1379a4 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -502,12 +502,13 @@ static int wl1271_reg_notify(struct wiphy *wiphy,
502 return 0; 502 return 0;
503} 503}
504 504
505static int wl1271_set_rx_streaming(struct wl1271 *wl, bool enable) 505static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
506 bool enable)
506{ 507{
507 int ret = 0; 508 int ret = 0;
508 509
509 /* we should hold wl->mutex */ 510 /* we should hold wl->mutex */
510 ret = wl1271_acx_ps_rx_streaming(wl, enable); 511 ret = wl1271_acx_ps_rx_streaming(wl, wlvif, enable);
511 if (ret < 0) 512 if (ret < 0)
512 goto out; 513 goto out;
513 514
@@ -523,7 +524,7 @@ out:
523 * this function is being called when the rx_streaming interval 524 * this function is being called when the rx_streaming interval
524 * has beed changed or rx_streaming should be disabled 525 * has beed changed or rx_streaming should be disabled
525 */ 526 */
526int wl1271_recalc_rx_streaming(struct wl1271 *wl) 527int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif)
527{ 528{
528 int ret = 0; 529 int ret = 0;
529 int period = wl->conf.rx_streaming.interval; 530 int period = wl->conf.rx_streaming.interval;
@@ -537,11 +538,11 @@ int wl1271_recalc_rx_streaming(struct wl1271 *wl)
537 test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) && 538 test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) &&
538 (wl->conf.rx_streaming.always || 539 (wl->conf.rx_streaming.always ||
539 test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) 540 test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
540 ret = wl1271_set_rx_streaming(wl, true); 541 ret = wl1271_set_rx_streaming(wl, wlvif, true);
541 else { 542 else {
542 ret = wl1271_set_rx_streaming(wl, false); 543 ret = wl1271_set_rx_streaming(wl, wlvif, false);
543 /* don't cancel_work_sync since we might deadlock */ 544 /* don't cancel_work_sync since we might deadlock */
544 del_timer_sync(&wl->rx_streaming_timer); 545 del_timer_sync(&wlvif->rx_streaming_timer);
545 } 546 }
546out: 547out:
547 return ret; 548 return ret;
@@ -550,8 +551,9 @@ out:
550static void wl1271_rx_streaming_enable_work(struct work_struct *work) 551static void wl1271_rx_streaming_enable_work(struct work_struct *work)
551{ 552{
552 int ret; 553 int ret;
553 struct wl1271 *wl = 554 struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
554 container_of(work, struct wl1271, rx_streaming_enable_work); 555 rx_streaming_enable_work);
556 struct wl1271 *wl = wlvif->wl;
555 557
556 mutex_lock(&wl->mutex); 558 mutex_lock(&wl->mutex);
557 559
@@ -568,12 +570,12 @@ static void wl1271_rx_streaming_enable_work(struct work_struct *work)
568 if (ret < 0) 570 if (ret < 0)
569 goto out; 571 goto out;
570 572
571 ret = wl1271_set_rx_streaming(wl, true); 573 ret = wl1271_set_rx_streaming(wl, wlvif, true);
572 if (ret < 0) 574 if (ret < 0)
573 goto out_sleep; 575 goto out_sleep;
574 576
575 /* stop it after some time of inactivity */ 577 /* stop it after some time of inactivity */
576 mod_timer(&wl->rx_streaming_timer, 578 mod_timer(&wlvif->rx_streaming_timer,
577 jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration)); 579 jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration));
578 580
579out_sleep: 581out_sleep:
@@ -585,8 +587,9 @@ out:
585static void wl1271_rx_streaming_disable_work(struct work_struct *work) 587static void wl1271_rx_streaming_disable_work(struct work_struct *work)
586{ 588{
587 int ret; 589 int ret;
588 struct wl1271 *wl = 590 struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
589 container_of(work, struct wl1271, rx_streaming_disable_work); 591 rx_streaming_disable_work);
592 struct wl1271 *wl = wlvif->wl;
590 593
591 mutex_lock(&wl->mutex); 594 mutex_lock(&wl->mutex);
592 595
@@ -597,7 +600,7 @@ static void wl1271_rx_streaming_disable_work(struct work_struct *work)
597 if (ret < 0) 600 if (ret < 0)
598 goto out; 601 goto out;
599 602
600 ret = wl1271_set_rx_streaming(wl, false); 603 ret = wl1271_set_rx_streaming(wl, wlvif, false);
601 if (ret) 604 if (ret)
602 goto out_sleep; 605 goto out_sleep;
603 606
@@ -609,8 +612,9 @@ out:
609 612
610static void wl1271_rx_streaming_timer(unsigned long data) 613static void wl1271_rx_streaming_timer(unsigned long data)
611{ 614{
612 struct wl1271 *wl = (struct wl1271 *)data; 615 struct wl12xx_vif *wlvif = (struct wl12xx_vif *)data;
613 ieee80211_queue_work(wl->hw, &wl->rx_streaming_disable_work); 616 struct wl1271 *wl = wlvif->wl;
617 ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work);
614} 618}
615 619
616static void wl1271_conf_init(struct wl1271 *wl) 620static void wl1271_conf_init(struct wl1271 *wl)
@@ -1827,9 +1831,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1827 cancel_delayed_work_sync(&wl->scan_complete_work); 1831 cancel_delayed_work_sync(&wl->scan_complete_work);
1828 cancel_work_sync(&wl->netstack_work); 1832 cancel_work_sync(&wl->netstack_work);
1829 cancel_work_sync(&wl->tx_work); 1833 cancel_work_sync(&wl->tx_work);
1830 del_timer_sync(&wl->rx_streaming_timer);
1831 cancel_work_sync(&wl->rx_streaming_enable_work);
1832 cancel_work_sync(&wl->rx_streaming_disable_work);
1833 cancel_delayed_work_sync(&wl->elp_work); 1834 cancel_delayed_work_sync(&wl->elp_work);
1834 1835
1835 /* let's notify MAC80211 about the remaining pending TX frames */ 1836 /* let's notify MAC80211 about the remaining pending TX frames */
@@ -1960,9 +1961,16 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
1960 wlvif->rate_set = CONF_TX_RATE_MASK_BASIC; 1961 wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
1961 wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT; 1962 wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT;
1962 1963
1964 INIT_WORK(&wlvif->rx_streaming_enable_work,
1965 wl1271_rx_streaming_enable_work);
1966 INIT_WORK(&wlvif->rx_streaming_disable_work,
1967 wl1271_rx_streaming_disable_work);
1963 INIT_DELAYED_WORK(&wlvif->pspoll_work, wl1271_pspoll_work); 1968 INIT_DELAYED_WORK(&wlvif->pspoll_work, wl1271_pspoll_work);
1964 INIT_LIST_HEAD(&wlvif->list); 1969 INIT_LIST_HEAD(&wlvif->list);
1965 1970
1971 setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
1972 (unsigned long) wlvif);
1973
1966 return 0; 1974 return 0;
1967} 1975}
1968 1976
@@ -2203,6 +2211,9 @@ deinit:
2203 wl->sta_count--; 2211 wl->sta_count--;
2204 2212
2205 mutex_unlock(&wl->mutex); 2213 mutex_unlock(&wl->mutex);
2214 del_timer_sync(&wlvif->rx_streaming_timer);
2215 cancel_work_sync(&wlvif->rx_streaming_enable_work);
2216 cancel_work_sync(&wlvif->rx_streaming_disable_work);
2206 cancel_delayed_work_sync(&wlvif->pspoll_work); 2217 cancel_delayed_work_sync(&wlvif->pspoll_work);
2207 2218
2208 mutex_lock(&wl->mutex); 2219 mutex_lock(&wl->mutex);
@@ -4903,10 +4914,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4903 INIT_WORK(&wl->tx_work, wl1271_tx_work); 4914 INIT_WORK(&wl->tx_work, wl1271_tx_work);
4904 INIT_WORK(&wl->recovery_work, wl1271_recovery_work); 4915 INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
4905 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); 4916 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
4906 INIT_WORK(&wl->rx_streaming_enable_work,
4907 wl1271_rx_streaming_enable_work);
4908 INIT_WORK(&wl->rx_streaming_disable_work,
4909 wl1271_rx_streaming_disable_work);
4910 4917
4911 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); 4918 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
4912 if (!wl->freezable_wq) { 4919 if (!wl->freezable_wq) {
@@ -4930,8 +4937,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4930 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; 4937 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
4931 wl->system_hlid = WL12XX_SYSTEM_HLID; 4938 wl->system_hlid = WL12XX_SYSTEM_HLID;
4932 wl->active_sta_count = 0; 4939 wl->active_sta_count = 0;
4933 setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer,
4934 (unsigned long) wl);
4935 wl->fwlog_size = 0; 4940 wl->fwlog_size = 0;
4936 init_waitqueue_head(&wl->fwlog_waitq); 4941 init_waitqueue_head(&wl->fwlog_waitq);
4937 4942
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 9cfa0b25a6f8..dd2f8b714a7f 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -28,6 +28,7 @@
28#include "acx.h" 28#include "acx.h"
29#include "reg.h" 29#include "reg.h"
30#include "rx.h" 30#include "rx.h"
31#include "tx.h"
31#include "io.h" 32#include "io.h"
32 33
33static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status, 34static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status,
@@ -96,7 +97,7 @@ static void wl1271_rx_status(struct wl1271 *wl,
96} 97}
97 98
98static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, 99static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
99 bool unaligned) 100 bool unaligned, u8 *hlid)
100{ 101{
101 struct wl1271_rx_descriptor *desc; 102 struct wl1271_rx_descriptor *desc;
102 struct sk_buff *skb; 103 struct sk_buff *skb;
@@ -159,6 +160,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
159 * payload aligned to 4 bytes. 160 * payload aligned to 4 bytes.
160 */ 161 */
161 memcpy(buf, data + sizeof(*desc), length - sizeof(*desc)); 162 memcpy(buf, data + sizeof(*desc), length - sizeof(*desc));
163 *hlid = desc->hlid;
162 164
163 hdr = (struct ieee80211_hdr *)skb->data; 165 hdr = (struct ieee80211_hdr *)skb->data;
164 if (ieee80211_is_beacon(hdr->frame_control)) 166 if (ieee80211_is_beacon(hdr->frame_control))
@@ -169,10 +171,10 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
169 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); 171 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
170 172
171 seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; 173 seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
172 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d", skb, 174 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d hlid %d", skb,
173 skb->len - desc->pad_len, 175 skb->len - desc->pad_len,
174 beacon ? "beacon" : "", 176 beacon ? "beacon" : "",
175 seq_num); 177 seq_num, *hlid);
176 178
177 skb_trim(skb, skb->len - desc->pad_len); 179 skb_trim(skb, skb->len - desc->pad_len);
178 180
@@ -185,8 +187,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
185void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) 187void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
186{ 188{
187 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; 189 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
188 struct ieee80211_vif *vif = wl->vif; /* TODO: get as param */ 190 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
189 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
190 u32 buf_size; 191 u32 buf_size;
191 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 192 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
192 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 193 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
@@ -194,8 +195,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
194 u32 mem_block; 195 u32 mem_block;
195 u32 pkt_length; 196 u32 pkt_length;
196 u32 pkt_offset; 197 u32 pkt_offset;
197 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 198 u8 hlid;
198 bool had_data = false;
199 bool unaligned = false; 199 bool unaligned = false;
200 200
201 while (drv_rx_counter != fw_rx_counter) { 201 while (drv_rx_counter != fw_rx_counter) {
@@ -255,8 +255,11 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
255 */ 255 */
256 if (wl1271_rx_handle_data(wl, 256 if (wl1271_rx_handle_data(wl,
257 wl->aggr_buf + pkt_offset, 257 wl->aggr_buf + pkt_offset,
258 pkt_length, unaligned) == 1) 258 pkt_length, unaligned,
259 had_data = true; 259 &hlid) == 1) {
260 WARN_ON(hlid >= WL12XX_MAX_LINKS);
261 __set_bit(hlid, active_hlids);
262 }
260 263
261 wl->rx_counter++; 264 wl->rx_counter++;
262 drv_rx_counter++; 265 drv_rx_counter++;
@@ -272,17 +275,5 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
272 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) 275 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION)
273 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); 276 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
274 277
275 if (!is_ap && wl->conf.rx_streaming.interval && had_data && 278 wl12xx_rearm_rx_streaming(wl, active_hlids);
276 (wl->conf.rx_streaming.always ||
277 test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) {
278 u32 timeout = wl->conf.rx_streaming.duration;
279
280 /* restart rx streaming */
281 if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags))
282 ieee80211_queue_work(wl->hw,
283 &wl->rx_streaming_enable_work);
284
285 mod_timer(&wl->rx_streaming_timer,
286 jiffies + msecs_to_jiffies(timeout));
287 }
288} 279}
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 8c35d37ba600..a06aa4e8df7b 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -643,21 +643,58 @@ static bool wl1271_tx_is_data_present(struct sk_buff *skb)
643 return ieee80211_is_data_present(hdr->frame_control); 643 return ieee80211_is_data_present(hdr->frame_control);
644} 644}
645 645
646void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids)
647{
648 struct wl12xx_vif *wlvif;
649 u32 timeout;
650 u8 hlid;
651
652 if (!wl->conf.rx_streaming.interval)
653 return;
654
655 if (!wl->conf.rx_streaming.always &&
656 !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))
657 return;
658
659 timeout = wl->conf.rx_streaming.duration;
660 wl12xx_for_each_wlvif_sta(wl, wlvif) {
661 bool found = false;
662 for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) {
663 if (test_bit(hlid, wlvif->links_map)) {
664 found = true;
665 break;
666 }
667 }
668
669 if (!found)
670 continue;
671
672 /* enable rx streaming */
673 if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags))
674 ieee80211_queue_work(wl->hw,
675 &wlvif->rx_streaming_enable_work);
676
677 mod_timer(&wlvif->rx_streaming_timer,
678 jiffies + msecs_to_jiffies(timeout));
679 }
680}
681
646void wl1271_tx_work_locked(struct wl1271 *wl) 682void wl1271_tx_work_locked(struct wl1271 *wl)
647{ 683{
648 struct wl12xx_vif *wlvif; 684 struct wl12xx_vif *wlvif;
649 struct sk_buff *skb; 685 struct sk_buff *skb;
686 struct wl1271_tx_hw_descr *desc;
650 u32 buf_offset = 0; 687 u32 buf_offset = 0;
651 bool sent_packets = false; 688 bool sent_packets = false;
652 bool had_data = false; 689 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
653 /* TODO: save bitmap of relevant stations */
654 bool is_sta = false;
655 int ret; 690 int ret;
656 691
657 if (unlikely(wl->state == WL1271_STATE_OFF)) 692 if (unlikely(wl->state == WL1271_STATE_OFF))
658 return; 693 return;
659 694
660 while ((skb = wl1271_skb_dequeue(wl))) { 695 while ((skb = wl1271_skb_dequeue(wl))) {
696 bool has_data = false;
697
661 wlvif = NULL; 698 wlvif = NULL;
662 if (!wl12xx_is_dummy_packet(wl, skb)) { 699 if (!wl12xx_is_dummy_packet(wl, skb)) {
663 struct ieee80211_tx_info *info; 700 struct ieee80211_tx_info *info;
@@ -667,9 +704,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
667 vif = info->control.vif; 704 vif = info->control.vif;
668 wlvif = wl12xx_vif_to_data(vif); 705 wlvif = wl12xx_vif_to_data(vif);
669 } 706 }
670 707 has_data = wlvif && wl1271_tx_is_data_present(skb);
671 if (wl1271_tx_is_data_present(skb))
672 had_data = true;
673 708
674 ret = wl1271_prepare_tx_frame(wl, wlvif, skb, buf_offset); 709 ret = wl1271_prepare_tx_frame(wl, wlvif, skb, buf_offset);
675 if (ret == -EAGAIN) { 710 if (ret == -EAGAIN) {
@@ -698,8 +733,10 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
698 } 733 }
699 buf_offset += ret; 734 buf_offset += ret;
700 wl->tx_packets_count++; 735 wl->tx_packets_count++;
701 if (wlvif && wlvif->bss_type == BSS_TYPE_STA_BSS) 736 if (has_data) {
702 is_sta = true; 737 desc = (struct wl1271_tx_hw_descr *) skb->data;
738 __set_bit(desc->hlid, active_hlids);
739 }
703 } 740 }
704 741
705out_ack: 742out_ack:
@@ -719,19 +756,7 @@ out_ack:
719 756
720 wl1271_handle_tx_low_watermark(wl); 757 wl1271_handle_tx_low_watermark(wl);
721 } 758 }
722 if (is_sta && wl->conf.rx_streaming.interval && had_data && 759 wl12xx_rearm_rx_streaming(wl, active_hlids);
723 (wl->conf.rx_streaming.always ||
724 test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) {
725 u32 timeout = wl->conf.rx_streaming.duration;
726
727 /* enable rx streaming */
728 if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags))
729 ieee80211_queue_work(wl->hw,
730 &wl->rx_streaming_enable_work);
731
732 mod_timer(&wl->rx_streaming_timer,
733 jiffies + msecs_to_jiffies(timeout));
734 }
735} 760}
736 761
737void wl1271_tx_work(struct work_struct *work) 762void wl1271_tx_work(struct work_struct *work)
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index fe29ff524e9a..2dbb24e6d541 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -220,6 +220,7 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
220void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); 220void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
221void wl1271_handle_tx_low_watermark(struct wl1271 *wl); 221void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
222bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); 222bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
223void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
223 224
224/* from main.c */ 225/* from main.c */
225void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); 226void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index d58488598d11..52d1cd0ddb6f 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -480,11 +480,6 @@ struct wl1271 {
480 /* The current band */ 480 /* The current band */
481 enum ieee80211_band band; 481 enum ieee80211_band band;
482 482
483 /* Rx Streaming */
484 struct work_struct rx_streaming_enable_work;
485 struct work_struct rx_streaming_disable_work;
486 struct timer_list rx_streaming_timer;
487
488 struct completion *elp_compl; 483 struct completion *elp_compl;
489 struct delayed_work elp_work; 484 struct delayed_work elp_work;
490 485
@@ -635,6 +630,11 @@ struct wl12xx_vif {
635 bool ba_support; 630 bool ba_support;
636 bool ba_allowed; 631 bool ba_allowed;
637 632
633 /* Rx Streaming */
634 struct work_struct rx_streaming_enable_work;
635 struct work_struct rx_streaming_disable_work;
636 struct timer_list rx_streaming_timer;
637
638 /* 638 /*
639 * This struct must be last! 639 * This struct must be last!
640 * data that has to be saved acrossed reconfigs (e.g. recovery) 640 * data that has to be saved acrossed reconfigs (e.g. recovery)
@@ -681,7 +681,7 @@ struct ieee80211_vif *wl12xx_wlvif_to_vif(struct wl12xx_vif *wlvif)
681 681
682int wl1271_plt_start(struct wl1271 *wl); 682int wl1271_plt_start(struct wl1271 *wl);
683int wl1271_plt_stop(struct wl1271 *wl); 683int wl1271_plt_stop(struct wl1271 *wl);
684int wl1271_recalc_rx_streaming(struct wl1271 *wl); 684int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif);
685void wl12xx_queue_recovery_work(struct wl1271 *wl); 685void wl12xx_queue_recovery_work(struct wl1271 *wl);
686size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); 686size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
687 687