diff options
author | Eliad Peller <eliad@wizery.com> | 2011-05-15 04:10:29 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-06-27 03:15:49 -0400 |
commit | 77ddaa108f727b5ef3be004b952d2c3d3ffc48e5 (patch) | |
tree | f8eea67a0930d2eb4879024abf2ce1df8ee66ccd /drivers/net/wireless/wl12xx/rx.c | |
parent | f84673d59773ded6efab640c5ee5f44b34116b75 (diff) |
wl12xx: add automatic rx streaming triggers
When rx_streaming.interval is non-zero, use automatic rx streaming.
Enable rx streaming on the each rx/tx packet, and disable it
rx_streaming.duration msecs later.
When rx_streaming.always=0 (default), rx streaming is enabled only
when there is a coex operation.
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/rx.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/rx.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 70091035e019..db230a503bf7 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c | |||
@@ -95,6 +95,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
95 | struct ieee80211_hdr *hdr; | 95 | struct ieee80211_hdr *hdr; |
96 | u8 *buf; | 96 | u8 *buf; |
97 | u8 beacon = 0; | 97 | u8 beacon = 0; |
98 | u8 is_data = 0; | ||
98 | 99 | ||
99 | /* | 100 | /* |
100 | * In PLT mode we seem to get frames and mac80211 warns about them, | 101 | * In PLT mode we seem to get frames and mac80211 warns about them, |
@@ -137,6 +138,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
137 | hdr = (struct ieee80211_hdr *)skb->data; | 138 | hdr = (struct ieee80211_hdr *)skb->data; |
138 | if (ieee80211_is_beacon(hdr->frame_control)) | 139 | if (ieee80211_is_beacon(hdr->frame_control)) |
139 | beacon = 1; | 140 | beacon = 1; |
141 | if (ieee80211_is_data_present(hdr->frame_control)) | ||
142 | is_data = 1; | ||
140 | 143 | ||
141 | wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); | 144 | wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); |
142 | 145 | ||
@@ -149,7 +152,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
149 | skb_queue_tail(&wl->deferred_rx_queue, skb); | 152 | skb_queue_tail(&wl->deferred_rx_queue, skb); |
150 | ieee80211_queue_work(wl->hw, &wl->netstack_work); | 153 | ieee80211_queue_work(wl->hw, &wl->netstack_work); |
151 | 154 | ||
152 | return 0; | 155 | return is_data; |
153 | } | 156 | } |
154 | 157 | ||
155 | void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | 158 | void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) |
@@ -162,6 +165,8 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | |||
162 | u32 mem_block; | 165 | u32 mem_block; |
163 | u32 pkt_length; | 166 | u32 pkt_length; |
164 | u32 pkt_offset; | 167 | u32 pkt_offset; |
168 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); | ||
169 | bool had_data = false; | ||
165 | 170 | ||
166 | while (drv_rx_counter != fw_rx_counter) { | 171 | while (drv_rx_counter != fw_rx_counter) { |
167 | buf_size = 0; | 172 | buf_size = 0; |
@@ -214,9 +219,11 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | |||
214 | * conditions, in that case the received frame will just | 219 | * conditions, in that case the received frame will just |
215 | * be dropped. | 220 | * be dropped. |
216 | */ | 221 | */ |
217 | wl1271_rx_handle_data(wl, | 222 | if (wl1271_rx_handle_data(wl, |
218 | wl->aggr_buf + pkt_offset, | 223 | wl->aggr_buf + pkt_offset, |
219 | pkt_length); | 224 | pkt_length) == 1) |
225 | had_data = true; | ||
226 | |||
220 | wl->rx_counter++; | 227 | wl->rx_counter++; |
221 | drv_rx_counter++; | 228 | drv_rx_counter++; |
222 | drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; | 229 | drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; |
@@ -230,6 +237,20 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | |||
230 | */ | 237 | */ |
231 | if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) | 238 | if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) |
232 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | 239 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); |
240 | |||
241 | if (!is_ap && wl->conf.rx_streaming.interval && had_data && | ||
242 | (wl->conf.rx_streaming.always || | ||
243 | test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) { | ||
244 | u32 timeout = wl->conf.rx_streaming.duration; | ||
245 | |||
246 | /* restart rx streaming */ | ||
247 | if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags)) | ||
248 | ieee80211_queue_work(wl->hw, | ||
249 | &wl->rx_streaming_enable_work); | ||
250 | |||
251 | mod_timer(&wl->rx_streaming_timer, | ||
252 | jiffies + msecs_to_jiffies(timeout)); | ||
253 | } | ||
233 | } | 254 | } |
234 | 255 | ||
235 | void wl1271_set_default_filters(struct wl1271 *wl) | 256 | void wl1271_set_default_filters(struct wl1271 *wl) |