1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * This file is part of wl1251 |
4 | * |
5 | * Copyright (c) 1998-2007 Texas Instruments Incorporated |
6 | * Copyright (C) 2008 Nokia Corporation |
7 | */ |
8 | |
9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> |
11 | |
12 | #include "wl1251.h" |
13 | #include "reg.h" |
14 | #include "tx.h" |
15 | #include "ps.h" |
16 | #include "io.h" |
17 | #include "event.h" |
18 | |
19 | static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) |
20 | { |
21 | int used, data_in_count; |
22 | |
23 | data_in_count = wl->data_in_count; |
24 | |
25 | if (data_in_count < data_out_count) |
26 | /* data_in_count has wrapped */ |
27 | data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1; |
28 | |
29 | used = data_in_count - data_out_count; |
30 | |
31 | WARN_ON(used < 0); |
32 | WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM); |
33 | |
34 | if (used >= DP_TX_PACKET_RING_CHUNK_NUM) |
35 | return true; |
36 | else |
37 | return false; |
38 | } |
39 | |
40 | static int wl1251_tx_path_status(struct wl1251 *wl) |
41 | { |
42 | u32 status, addr, data_out_count; |
43 | bool busy; |
44 | |
45 | addr = wl->data_path->tx_control_addr; |
46 | status = wl1251_mem_read32(wl, addr); |
47 | data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK; |
48 | busy = wl1251_tx_double_buffer_busy(wl, data_out_count); |
49 | |
50 | if (busy) |
51 | return -EBUSY; |
52 | |
53 | return 0; |
54 | } |
55 | |
56 | static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb) |
57 | { |
58 | int i; |
59 | |
60 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) |
61 | if (wl->tx_frames[i] == NULL) { |
62 | wl->tx_frames[i] = skb; |
63 | return i; |
64 | } |
65 | |
66 | return -EBUSY; |
67 | } |
68 | |
69 | static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr, |
70 | struct ieee80211_tx_info *control, u16 fc) |
71 | { |
72 | *(u16 *)&tx_hdr->control = 0; |
73 | |
74 | tx_hdr->control.rate_policy = 0; |
75 | |
76 | /* 802.11 packets */ |
77 | tx_hdr->control.packet_type = 0; |
78 | |
79 | /* Also disable retry and ACK policy for injected packets */ |
80 | if ((control->flags & IEEE80211_TX_CTL_NO_ACK) || |
81 | (control->flags & IEEE80211_TX_CTL_INJECTED)) { |
82 | tx_hdr->control.rate_policy = 1; |
83 | tx_hdr->control.ack_policy = 1; |
84 | } |
85 | |
86 | tx_hdr->control.tx_complete = 1; |
87 | |
88 | if ((fc & IEEE80211_FTYPE_DATA) && |
89 | ((fc & IEEE80211_STYPE_QOS_DATA) || |
90 | (fc & IEEE80211_STYPE_QOS_NULLFUNC))) |
91 | tx_hdr->control.qos = 1; |
92 | } |
93 | |
94 | /* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */ |
95 | #define MAX_MSDU_SECURITY_LENGTH 16 |
96 | #define MAX_MPDU_SECURITY_LENGTH 16 |
97 | #define WLAN_QOS_HDR_LEN 26 |
98 | #define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \ |
99 | WLAN_QOS_HDR_LEN) |
100 | #define HW_BLOCK_SIZE 252 |
101 | static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr) |
102 | { |
103 | u16 payload_len, frag_threshold, mem_blocks; |
104 | u16 num_mpdus, mem_blocks_per_frag; |
105 | |
106 | frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
107 | tx_hdr->frag_threshold = cpu_to_le16(frag_threshold); |
108 | |
109 | payload_len = le16_to_cpu(tx_hdr->length) + MAX_MSDU_SECURITY_LENGTH; |
110 | |
111 | if (payload_len > frag_threshold) { |
112 | mem_blocks_per_frag = |
113 | ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) / |
114 | HW_BLOCK_SIZE) + 1; |
115 | num_mpdus = payload_len / frag_threshold; |
116 | mem_blocks = num_mpdus * mem_blocks_per_frag; |
117 | payload_len -= num_mpdus * frag_threshold; |
118 | num_mpdus++; |
119 | |
120 | } else { |
121 | mem_blocks_per_frag = 0; |
122 | mem_blocks = 0; |
123 | num_mpdus = 1; |
124 | } |
125 | |
126 | mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1; |
127 | |
128 | if (num_mpdus > 1) |
129 | mem_blocks += min(num_mpdus, mem_blocks_per_frag); |
130 | |
131 | tx_hdr->num_mem_blocks = mem_blocks; |
132 | } |
133 | |
134 | static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb, |
135 | struct ieee80211_tx_info *control) |
136 | { |
137 | struct tx_double_buffer_desc *tx_hdr; |
138 | struct ieee80211_rate *rate; |
139 | int id; |
140 | u16 fc; |
141 | |
142 | if (!skb) |
143 | return -EINVAL; |
144 | |
145 | id = wl1251_tx_id(wl, skb); |
146 | if (id < 0) |
147 | return id; |
148 | |
149 | fc = *(u16 *)skb->data; |
150 | tx_hdr = skb_push(skb, len: sizeof(*tx_hdr)); |
151 | |
152 | tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr)); |
153 | rate = ieee80211_get_tx_rate(hw: wl->hw, c: control); |
154 | tx_hdr->rate = cpu_to_le16(rate->hw_value); |
155 | tx_hdr->expiry_time = cpu_to_le32(1 << 16); |
156 | tx_hdr->id = id; |
157 | |
158 | tx_hdr->xmit_queue = wl1251_tx_get_queue(queue: skb_get_queue_mapping(skb)); |
159 | |
160 | wl1251_tx_control(tx_hdr, control, fc); |
161 | wl1251_tx_frag_block_num(tx_hdr); |
162 | |
163 | return 0; |
164 | } |
165 | |
166 | /* We copy the packet to the target */ |
167 | static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, |
168 | struct ieee80211_tx_info *control) |
169 | { |
170 | struct tx_double_buffer_desc *tx_hdr; |
171 | int len; |
172 | u32 addr; |
173 | |
174 | if (!skb) |
175 | return -EINVAL; |
176 | |
177 | tx_hdr = (struct tx_double_buffer_desc *) skb->data; |
178 | |
179 | if (control->control.hw_key && |
180 | control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { |
181 | int hdrlen; |
182 | __le16 fc; |
183 | u16 length; |
184 | u8 *pos; |
185 | |
186 | fc = *(__le16 *)(skb->data + sizeof(*tx_hdr)); |
187 | length = le16_to_cpu(tx_hdr->length) + WL1251_TKIP_IV_SPACE; |
188 | tx_hdr->length = cpu_to_le16(length); |
189 | |
190 | hdrlen = ieee80211_hdrlen(fc); |
191 | |
192 | pos = skb_push(skb, WL1251_TKIP_IV_SPACE); |
193 | memmove(pos, pos + WL1251_TKIP_IV_SPACE, |
194 | sizeof(*tx_hdr) + hdrlen); |
195 | } |
196 | |
197 | /* Revisit. This is a workaround for getting non-aligned packets. |
198 | This happens at least with EAPOL packets from the user space. |
199 | Our DMA requires packets to be aligned on a 4-byte boundary. |
200 | */ |
201 | if (unlikely((long)skb->data & 0x03)) { |
202 | int offset = (4 - (long)skb->data) & 0x03; |
203 | wl1251_debug(DEBUG_TX, "skb offset %d" , offset); |
204 | |
205 | /* check whether the current skb can be used */ |
206 | if (skb_cloned(skb) || (skb_tailroom(skb) < offset)) { |
207 | struct sk_buff *newskb = skb_copy_expand(skb, newheadroom: 0, newtailroom: 3, |
208 | GFP_KERNEL); |
209 | |
210 | if (unlikely(newskb == NULL)) |
211 | return -EINVAL; |
212 | |
213 | tx_hdr = (struct tx_double_buffer_desc *) newskb->data; |
214 | |
215 | dev_kfree_skb_any(skb); |
216 | wl->tx_frames[tx_hdr->id] = skb = newskb; |
217 | |
218 | offset = (4 - (long)skb->data) & 0x03; |
219 | wl1251_debug(DEBUG_TX, "new skb offset %d" , offset); |
220 | } |
221 | |
222 | /* align the buffer on a 4-byte boundary */ |
223 | if (offset) { |
224 | unsigned char *src = skb->data; |
225 | skb_reserve(skb, len: offset); |
226 | memmove(skb->data, src, skb->len); |
227 | tx_hdr = (struct tx_double_buffer_desc *) skb->data; |
228 | } |
229 | } |
230 | |
231 | /* Our skb->data at this point includes the HW header */ |
232 | len = WL1251_TX_ALIGN(skb->len); |
233 | |
234 | if (wl->data_in_count & 0x1) |
235 | addr = wl->data_path->tx_packet_ring_addr + |
236 | wl->data_path->tx_packet_ring_chunk_size; |
237 | else |
238 | addr = wl->data_path->tx_packet_ring_addr; |
239 | |
240 | wl1251_mem_write(wl, addr, buf: skb->data, len); |
241 | |
242 | wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x " |
243 | "queue %d" , tx_hdr->id, skb, tx_hdr->length, |
244 | tx_hdr->rate, tx_hdr->xmit_queue); |
245 | |
246 | return 0; |
247 | } |
248 | |
249 | static void wl1251_tx_trigger(struct wl1251 *wl) |
250 | { |
251 | u32 data, addr; |
252 | |
253 | if (wl->data_in_count & 0x1) { |
254 | addr = ACX_REG_INTERRUPT_TRIG_H; |
255 | data = INTR_TRIG_TX_PROC1; |
256 | } else { |
257 | addr = ACX_REG_INTERRUPT_TRIG; |
258 | data = INTR_TRIG_TX_PROC0; |
259 | } |
260 | |
261 | wl1251_reg_write32(wl, addr, val: data); |
262 | |
263 | /* Bumping data in */ |
264 | wl->data_in_count = (wl->data_in_count + 1) & |
265 | TX_STATUS_DATA_OUT_COUNT_MASK; |
266 | } |
267 | |
268 | static void enable_tx_for_packet_injection(struct wl1251 *wl) |
269 | { |
270 | int ret; |
271 | |
272 | ret = wl1251_cmd_join(wl, bss_type: BSS_TYPE_STA_BSS, channel: wl->channel, |
273 | beacon_interval: wl->beacon_int, dtim_interval: wl->dtim_period); |
274 | if (ret < 0) { |
275 | wl1251_warning("join failed" ); |
276 | return; |
277 | } |
278 | |
279 | ret = wl1251_event_wait(wl, mask: JOIN_EVENT_COMPLETE_ID, timeout_ms: 100); |
280 | if (ret < 0) { |
281 | wl1251_warning("join timeout" ); |
282 | return; |
283 | } |
284 | |
285 | wl->joined = true; |
286 | } |
287 | |
288 | /* caller must hold wl->mutex */ |
289 | static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb) |
290 | { |
291 | struct ieee80211_tx_info *info; |
292 | int ret = 0; |
293 | u8 idx; |
294 | |
295 | info = IEEE80211_SKB_CB(skb); |
296 | |
297 | if (info->control.hw_key) { |
298 | if (unlikely(wl->monitor_present)) |
299 | return -EINVAL; |
300 | |
301 | idx = info->control.hw_key->hw_key_idx; |
302 | if (unlikely(wl->default_key != idx)) { |
303 | ret = wl1251_acx_default_key(wl, key_id: idx); |
304 | if (ret < 0) |
305 | return ret; |
306 | } |
307 | } |
308 | |
309 | /* Enable tx path in monitor mode for packet injection */ |
310 | if ((wl->vif == NULL) && !wl->joined) |
311 | enable_tx_for_packet_injection(wl); |
312 | |
313 | ret = wl1251_tx_path_status(wl); |
314 | if (ret < 0) |
315 | return ret; |
316 | |
317 | ret = wl1251_tx_fill_hdr(wl, skb, control: info); |
318 | if (ret < 0) |
319 | return ret; |
320 | |
321 | ret = wl1251_tx_send_packet(wl, skb, control: info); |
322 | if (ret < 0) |
323 | return ret; |
324 | |
325 | wl1251_tx_trigger(wl); |
326 | |
327 | return ret; |
328 | } |
329 | |
330 | void wl1251_tx_work(struct work_struct *work) |
331 | { |
332 | struct wl1251 *wl = container_of(work, struct wl1251, tx_work); |
333 | struct sk_buff *skb; |
334 | bool woken_up = false; |
335 | int ret; |
336 | |
337 | mutex_lock(&wl->mutex); |
338 | |
339 | if (unlikely(wl->state == WL1251_STATE_OFF)) |
340 | goto out; |
341 | |
342 | while ((skb = skb_dequeue(list: &wl->tx_queue))) { |
343 | if (!woken_up) { |
344 | ret = wl1251_ps_elp_wakeup(wl); |
345 | if (ret < 0) |
346 | goto out; |
347 | woken_up = true; |
348 | } |
349 | |
350 | ret = wl1251_tx_frame(wl, skb); |
351 | if (ret == -EBUSY) { |
352 | skb_queue_head(list: &wl->tx_queue, newsk: skb); |
353 | goto out; |
354 | } else if (ret < 0) { |
355 | dev_kfree_skb(skb); |
356 | goto out; |
357 | } |
358 | } |
359 | |
360 | out: |
361 | if (woken_up) |
362 | wl1251_ps_elp_sleep(wl); |
363 | |
364 | mutex_unlock(lock: &wl->mutex); |
365 | } |
366 | |
367 | static const char *wl1251_tx_parse_status(u8 status) |
368 | { |
369 | /* 8 bit status field, one character per bit plus null */ |
370 | static char buf[9]; |
371 | int i = 0; |
372 | |
373 | memset(buf, 0, sizeof(buf)); |
374 | |
375 | if (status & TX_DMA_ERROR) |
376 | buf[i++] = 'm'; |
377 | if (status & TX_DISABLED) |
378 | buf[i++] = 'd'; |
379 | if (status & TX_RETRY_EXCEEDED) |
380 | buf[i++] = 'r'; |
381 | if (status & TX_TIMEOUT) |
382 | buf[i++] = 't'; |
383 | if (status & TX_KEY_NOT_FOUND) |
384 | buf[i++] = 'k'; |
385 | if (status & TX_ENCRYPT_FAIL) |
386 | buf[i++] = 'e'; |
387 | if (status & TX_UNAVAILABLE_PRIORITY) |
388 | buf[i++] = 'p'; |
389 | |
390 | /* bit 0 is unused apparently */ |
391 | |
392 | return buf; |
393 | } |
394 | |
395 | static void wl1251_tx_packet_cb(struct wl1251 *wl, |
396 | struct tx_result *result) |
397 | { |
398 | struct ieee80211_tx_info *info; |
399 | struct sk_buff *skb; |
400 | int hdrlen; |
401 | u8 *frame; |
402 | |
403 | skb = wl->tx_frames[result->id]; |
404 | if (skb == NULL) { |
405 | wl1251_error("SKB for packet %d is NULL" , result->id); |
406 | return; |
407 | } |
408 | |
409 | info = IEEE80211_SKB_CB(skb); |
410 | |
411 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
412 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && |
413 | (result->status == TX_SUCCESS)) |
414 | info->flags |= IEEE80211_TX_STAT_ACK; |
415 | |
416 | info->status.rates[0].count = result->ack_failures + 1; |
417 | wl->stats.retry_count += result->ack_failures; |
418 | |
419 | /* |
420 | * We have to remove our private TX header before pushing |
421 | * the skb back to mac80211. |
422 | */ |
423 | frame = skb_pull(skb, len: sizeof(struct tx_double_buffer_desc)); |
424 | if (info->control.hw_key && |
425 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { |
426 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
427 | memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen); |
428 | skb_pull(skb, WL1251_TKIP_IV_SPACE); |
429 | } |
430 | |
431 | wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" |
432 | " status 0x%x (%s)" , |
433 | result->id, skb, result->ack_failures, result->rate, |
434 | result->status, wl1251_tx_parse_status(result->status)); |
435 | |
436 | |
437 | ieee80211_tx_status_skb(hw: wl->hw, skb); |
438 | |
439 | wl->tx_frames[result->id] = NULL; |
440 | } |
441 | |
442 | /* Called upon reception of a TX complete interrupt */ |
443 | void wl1251_tx_complete(struct wl1251 *wl) |
444 | { |
445 | int i, result_index, num_complete = 0, queue_len; |
446 | struct tx_result *result, *result_ptr; |
447 | unsigned long flags; |
448 | |
449 | if (unlikely(wl->state != WL1251_STATE_ON)) |
450 | return; |
451 | |
452 | result = kmalloc_array(FW_TX_CMPLT_BLOCK_SIZE, size: sizeof(*result), GFP_KERNEL); |
453 | if (!result) { |
454 | wl1251_error("can not allocate result buffer" ); |
455 | return; |
456 | } |
457 | |
458 | /* First we read the result */ |
459 | wl1251_mem_read(wl, addr: wl->data_path->tx_complete_addr, buf: result, |
460 | FW_TX_CMPLT_BLOCK_SIZE * sizeof(*result)); |
461 | |
462 | result_index = wl->next_tx_complete; |
463 | |
464 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) { |
465 | result_ptr = &result[result_index]; |
466 | |
467 | if (result_ptr->done_1 == 1 && |
468 | result_ptr->done_2 == 1) { |
469 | wl1251_tx_packet_cb(wl, result: result_ptr); |
470 | |
471 | result_ptr->done_1 = 0; |
472 | result_ptr->done_2 = 0; |
473 | |
474 | result_index = (result_index + 1) & |
475 | (FW_TX_CMPLT_BLOCK_SIZE - 1); |
476 | num_complete++; |
477 | } else { |
478 | break; |
479 | } |
480 | } |
481 | |
482 | queue_len = skb_queue_len(list_: &wl->tx_queue); |
483 | |
484 | if ((num_complete > 0) && (queue_len > 0)) { |
485 | /* firmware buffer has space, reschedule tx_work */ |
486 | wl1251_debug(DEBUG_TX, "tx_complete: reschedule tx_work" ); |
487 | ieee80211_queue_work(hw: wl->hw, work: &wl->tx_work); |
488 | } |
489 | |
490 | if (wl->tx_queue_stopped && |
491 | queue_len <= WL1251_TX_QUEUE_LOW_WATERMARK) { |
492 | /* tx_queue has space, restart queues */ |
493 | wl1251_debug(DEBUG_TX, "tx_complete: waking queues" ); |
494 | spin_lock_irqsave(&wl->wl_lock, flags); |
495 | ieee80211_wake_queues(hw: wl->hw); |
496 | wl->tx_queue_stopped = false; |
497 | spin_unlock_irqrestore(lock: &wl->wl_lock, flags); |
498 | } |
499 | |
500 | /* Every completed frame needs to be acknowledged */ |
501 | if (num_complete) { |
502 | /* |
503 | * If we've wrapped, we have to clear |
504 | * the results in 2 steps. |
505 | */ |
506 | if (result_index > wl->next_tx_complete) { |
507 | /* Only 1 write is needed */ |
508 | wl1251_mem_write(wl, |
509 | addr: wl->data_path->tx_complete_addr + |
510 | (wl->next_tx_complete * |
511 | sizeof(struct tx_result)), |
512 | buf: &result[wl->next_tx_complete], |
513 | len: num_complete * |
514 | sizeof(struct tx_result)); |
515 | |
516 | |
517 | } else if (result_index < wl->next_tx_complete) { |
518 | /* 2 writes are needed */ |
519 | wl1251_mem_write(wl, |
520 | addr: wl->data_path->tx_complete_addr + |
521 | (wl->next_tx_complete * |
522 | sizeof(struct tx_result)), |
523 | buf: &result[wl->next_tx_complete], |
524 | len: (FW_TX_CMPLT_BLOCK_SIZE - |
525 | wl->next_tx_complete) * |
526 | sizeof(struct tx_result)); |
527 | |
528 | wl1251_mem_write(wl, |
529 | addr: wl->data_path->tx_complete_addr, |
530 | buf: result, |
531 | len: (num_complete - |
532 | FW_TX_CMPLT_BLOCK_SIZE + |
533 | wl->next_tx_complete) * |
534 | sizeof(struct tx_result)); |
535 | |
536 | } else { |
537 | /* We have to write the whole array */ |
538 | wl1251_mem_write(wl, |
539 | addr: wl->data_path->tx_complete_addr, |
540 | buf: result, |
541 | FW_TX_CMPLT_BLOCK_SIZE * |
542 | sizeof(struct tx_result)); |
543 | } |
544 | |
545 | } |
546 | |
547 | kfree(objp: result); |
548 | wl->next_tx_complete = result_index; |
549 | } |
550 | |
551 | /* caller must hold wl->mutex */ |
552 | void wl1251_tx_flush(struct wl1251 *wl) |
553 | { |
554 | int i; |
555 | struct sk_buff *skb; |
556 | struct ieee80211_tx_info *info; |
557 | |
558 | /* TX failure */ |
559 | /* control->flags = 0; FIXME */ |
560 | |
561 | while ((skb = skb_dequeue(list: &wl->tx_queue))) { |
562 | info = IEEE80211_SKB_CB(skb); |
563 | |
564 | wl1251_debug(DEBUG_TX, "flushing skb 0x%p" , skb); |
565 | |
566 | if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) |
567 | continue; |
568 | |
569 | ieee80211_tx_status_skb(hw: wl->hw, skb); |
570 | } |
571 | |
572 | for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) |
573 | if (wl->tx_frames[i] != NULL) { |
574 | skb = wl->tx_frames[i]; |
575 | info = IEEE80211_SKB_CB(skb); |
576 | |
577 | if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) |
578 | continue; |
579 | |
580 | ieee80211_tx_status_skb(hw: wl->hw, skb); |
581 | wl->tx_frames[i] = NULL; |
582 | } |
583 | } |
584 | |