aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index e3dc13c4d01a..b13b37330036 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -52,7 +52,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
52 int id, ret = -EBUSY; 52 int id, ret = -EBUSY;
53 53
54 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) 54 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
55 return -EBUSY; 55 return -EAGAIN;
56 56
57 /* allocate free identifier for the packet */ 57 /* allocate free identifier for the packet */
58 id = wl1271_tx_id(wl, skb); 58 id = wl1271_tx_id(wl, skb);
@@ -210,7 +210,8 @@ void wl1271_tx_work(struct work_struct *work)
210 struct sk_buff *skb; 210 struct sk_buff *skb;
211 bool woken_up = false; 211 bool woken_up = false;
212 u32 sta_rates = 0; 212 u32 sta_rates = 0;
213 u32 buf_offset; 213 u32 buf_offset = 0;
214 bool sent_packets = false;
214 int ret; 215 int ret;
215 216
216 /* check if the rates supported by the AP have changed */ 217 /* check if the rates supported by the AP have changed */
@@ -233,9 +234,6 @@ void wl1271_tx_work(struct work_struct *work)
233 wl1271_acx_rate_policies(wl); 234 wl1271_acx_rate_policies(wl);
234 } 235 }
235 236
236 /* Prepare the transfer buffer, by aggregating all
237 * available packets */
238 buf_offset = 0;
239 while ((skb = skb_dequeue(&wl->tx_queue))) { 237 while ((skb = skb_dequeue(&wl->tx_queue))) {
240 if (!woken_up) { 238 if (!woken_up) {
241 ret = wl1271_ps_elp_wakeup(wl, false); 239 ret = wl1271_ps_elp_wakeup(wl, false);
@@ -245,10 +243,20 @@ void wl1271_tx_work(struct work_struct *work)
245 } 243 }
246 244
247 ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); 245 ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
248 if (ret == -EBUSY) { 246 if (ret == -EAGAIN) {
249 /* 247 /*
250 * Either the firmware buffer is full, or the 248 * Aggregation buffer is full.
251 * aggregation buffer is. 249 * Flush buffer and try again.
250 */
251 skb_queue_head(&wl->tx_queue, skb);
252 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
253 buf_offset, true);
254 sent_packets = true;
255 buf_offset = 0;
256 continue;
257 } else if (ret == -EBUSY) {
258 /*
259 * Firmware buffer is full.
252 * Queue back last skb, and stop aggregating. 260 * Queue back last skb, and stop aggregating.
253 */ 261 */
254 skb_queue_head(&wl->tx_queue, skb); 262 skb_queue_head(&wl->tx_queue, skb);
@@ -265,6 +273,9 @@ out_ack:
265 if (buf_offset) { 273 if (buf_offset) {
266 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 274 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
267 buf_offset, true); 275 buf_offset, true);
276 sent_packets = true;
277 }
278 if (sent_packets) {
268 /* interrupt the firmware with the new packets */ 279 /* interrupt the firmware with the new packets */
269 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); 280 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
270 } 281 }