aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/rx.c')
-rw-r--r--drivers/net/wireless/wl12xx/rx.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 70091035e01..0450fb49dbb 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/gfp.h> 24#include <linux/gfp.h>
25#include <linux/sched.h>
25 26
26#include "wl12xx.h" 27#include "wl12xx.h"
27#include "acx.h" 28#include "acx.h"
@@ -95,6 +96,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
95 struct ieee80211_hdr *hdr; 96 struct ieee80211_hdr *hdr;
96 u8 *buf; 97 u8 *buf;
97 u8 beacon = 0; 98 u8 beacon = 0;
99 u8 is_data = 0;
98 100
99 /* 101 /*
100 * In PLT mode we seem to get frames and mac80211 warns about them, 102 * In PLT mode we seem to get frames and mac80211 warns about them,
@@ -106,6 +108,13 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
106 /* the data read starts with the descriptor */ 108 /* the data read starts with the descriptor */
107 desc = (struct wl1271_rx_descriptor *) data; 109 desc = (struct wl1271_rx_descriptor *) data;
108 110
111 if (desc->packet_class == WL12XX_RX_CLASS_LOGGER) {
112 size_t len = length - sizeof(*desc);
113 wl12xx_copy_fwlog(wl, data + sizeof(*desc), len);
114 wake_up_interruptible(&wl->fwlog_waitq);
115 return 0;
116 }
117
109 switch (desc->status & WL1271_RX_DESC_STATUS_MASK) { 118 switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
110 /* discard corrupted packets */ 119 /* discard corrupted packets */
111 case WL1271_RX_DESC_DRIVER_RX_Q_FAIL: 120 case WL1271_RX_DESC_DRIVER_RX_Q_FAIL:
@@ -137,6 +146,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
137 hdr = (struct ieee80211_hdr *)skb->data; 146 hdr = (struct ieee80211_hdr *)skb->data;
138 if (ieee80211_is_beacon(hdr->frame_control)) 147 if (ieee80211_is_beacon(hdr->frame_control))
139 beacon = 1; 148 beacon = 1;
149 if (ieee80211_is_data_present(hdr->frame_control))
150 is_data = 1;
140 151
141 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); 152 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
142 153
@@ -147,9 +158,9 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
147 skb_trim(skb, skb->len - desc->pad_len); 158 skb_trim(skb, skb->len - desc->pad_len);
148 159
149 skb_queue_tail(&wl->deferred_rx_queue, skb); 160 skb_queue_tail(&wl->deferred_rx_queue, skb);
150 ieee80211_queue_work(wl->hw, &wl->netstack_work); 161 queue_work(wl->freezable_wq, &wl->netstack_work);
151 162
152 return 0; 163 return is_data;
153} 164}
154 165
155void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) 166void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
@@ -162,6 +173,8 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
162 u32 mem_block; 173 u32 mem_block;
163 u32 pkt_length; 174 u32 pkt_length;
164 u32 pkt_offset; 175 u32 pkt_offset;
176 bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
177 bool had_data = false;
165 178
166 while (drv_rx_counter != fw_rx_counter) { 179 while (drv_rx_counter != fw_rx_counter) {
167 buf_size = 0; 180 buf_size = 0;
@@ -214,9 +227,11 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
214 * conditions, in that case the received frame will just 227 * conditions, in that case the received frame will just
215 * be dropped. 228 * be dropped.
216 */ 229 */
217 wl1271_rx_handle_data(wl, 230 if (wl1271_rx_handle_data(wl,
218 wl->aggr_buf + pkt_offset, 231 wl->aggr_buf + pkt_offset,
219 pkt_length); 232 pkt_length) == 1)
233 had_data = true;
234
220 wl->rx_counter++; 235 wl->rx_counter++;
221 drv_rx_counter++; 236 drv_rx_counter++;
222 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; 237 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
@@ -230,6 +245,20 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
230 */ 245 */
231 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) 246 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION)
232 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); 247 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
248
249 if (!is_ap && wl->conf.rx_streaming.interval && had_data &&
250 (wl->conf.rx_streaming.always ||
251 test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags))) {
252 u32 timeout = wl->conf.rx_streaming.duration;
253
254 /* restart rx streaming */
255 if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags))
256 ieee80211_queue_work(wl->hw,
257 &wl->rx_streaming_enable_work);
258
259 mod_timer(&wl->rx_streaming_timer,
260 jiffies + msecs_to_jiffies(timeout));
261 }
233} 262}
234 263
235void wl1271_set_default_filters(struct wl1271 *wl) 264void wl1271_set_default_filters(struct wl1271 *wl)