aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/tx.c')
-rw-r--r--drivers/net/wireless/wl12xx/tx.c67
1 files changed, 46 insertions, 21 deletions
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)