Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/athk/ath11k/dp.c
105569 views
1
// SPDX-License-Identifier: BSD-3-Clause-Clear
2
/*
3
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
5
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6
*/
7
8
#if defined(__FreeBSD__)
9
#include <asm/io.h>
10
#endif
11
#include <crypto/hash.h>
12
#include <linux/export.h>
13
#include "core.h"
14
#include "dp_tx.h"
15
#include "hal_tx.h"
16
#include "hif.h"
17
#include "debug.h"
18
#include "dp_rx.h"
19
#include "peer.h"
20
21
static void ath11k_dp_htt_htc_tx_complete(struct ath11k_base *ab,
22
struct sk_buff *skb)
23
{
24
dev_kfree_skb_any(skb);
25
}
26
27
void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
28
{
29
struct ath11k_base *ab = ar->ab;
30
struct ath11k_peer *peer;
31
32
/* TODO: Any other peer specific DP cleanup */
33
34
spin_lock_bh(&ab->base_lock);
35
peer = ath11k_peer_find(ab, vdev_id, addr);
36
if (!peer) {
37
ath11k_warn(ab, "failed to lookup peer %pM on vdev %d\n",
38
addr, vdev_id);
39
spin_unlock_bh(&ab->base_lock);
40
return;
41
}
42
43
ath11k_peer_rx_tid_cleanup(ar, peer);
44
peer->dp_setup_done = false;
45
crypto_free_shash(peer->tfm_mmic);
46
spin_unlock_bh(&ab->base_lock);
47
}
48
49
int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
50
{
51
struct ath11k_base *ab = ar->ab;
52
struct ath11k_peer *peer;
53
u32 reo_dest;
54
int ret = 0, tid;
55
56
/* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */
57
reo_dest = ar->dp.mac_id + 1;
58
ret = ath11k_wmi_set_peer_param(ar, addr, vdev_id,
59
WMI_PEER_SET_DEFAULT_ROUTING,
60
DP_RX_HASH_ENABLE | (reo_dest << 1));
61
62
if (ret) {
63
ath11k_warn(ab, "failed to set default routing %d peer :%pM vdev_id :%d\n",
64
ret, addr, vdev_id);
65
return ret;
66
}
67
68
for (tid = 0; tid <= IEEE80211_NUM_TIDS; tid++) {
69
ret = ath11k_peer_rx_tid_setup(ar, addr, vdev_id, tid, 1, 0,
70
HAL_PN_TYPE_NONE);
71
if (ret) {
72
ath11k_warn(ab, "failed to setup rxd tid queue for tid %d: %d\n",
73
tid, ret);
74
goto peer_clean;
75
}
76
}
77
78
ret = ath11k_peer_rx_frag_setup(ar, addr, vdev_id);
79
if (ret) {
80
ath11k_warn(ab, "failed to setup rx defrag context\n");
81
tid--;
82
goto peer_clean;
83
}
84
85
/* TODO: Setup other peer specific resource used in data path */
86
87
return 0;
88
89
peer_clean:
90
spin_lock_bh(&ab->base_lock);
91
92
peer = ath11k_peer_find(ab, vdev_id, addr);
93
if (!peer) {
94
ath11k_warn(ab, "failed to find the peer to del rx tid\n");
95
spin_unlock_bh(&ab->base_lock);
96
return -ENOENT;
97
}
98
99
for (; tid >= 0; tid--)
100
ath11k_peer_rx_tid_delete(ar, peer, tid);
101
102
spin_unlock_bh(&ab->base_lock);
103
104
return ret;
105
}
106
107
void ath11k_dp_srng_cleanup(struct ath11k_base *ab, struct dp_srng *ring)
108
{
109
if (!ring->vaddr_unaligned)
110
return;
111
112
if (ring->cached)
113
dma_free_noncoherent(ab->dev, ring->size, ring->vaddr_unaligned,
114
ring->paddr_unaligned, DMA_FROM_DEVICE);
115
else
116
dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
117
ring->paddr_unaligned);
118
119
ring->vaddr_unaligned = NULL;
120
}
121
122
static int ath11k_dp_srng_find_ring_in_mask(int ring_num, const u8 *grp_mask)
123
{
124
int ext_group_num;
125
u8 mask = 1 << ring_num;
126
127
for (ext_group_num = 0; ext_group_num < ATH11K_EXT_IRQ_GRP_NUM_MAX;
128
ext_group_num++) {
129
if (mask & grp_mask[ext_group_num])
130
return ext_group_num;
131
}
132
133
return -ENOENT;
134
}
135
136
static int ath11k_dp_srng_calculate_msi_group(struct ath11k_base *ab,
137
enum hal_ring_type type, int ring_num)
138
{
139
const u8 *grp_mask;
140
141
switch (type) {
142
case HAL_WBM2SW_RELEASE:
143
if (ring_num == DP_RX_RELEASE_RING_NUM) {
144
grp_mask = &ab->hw_params.ring_mask->rx_wbm_rel[0];
145
ring_num = 0;
146
} else {
147
grp_mask = &ab->hw_params.ring_mask->tx[0];
148
}
149
break;
150
case HAL_REO_EXCEPTION:
151
grp_mask = &ab->hw_params.ring_mask->rx_err[0];
152
break;
153
case HAL_REO_DST:
154
grp_mask = &ab->hw_params.ring_mask->rx[0];
155
break;
156
case HAL_REO_STATUS:
157
grp_mask = &ab->hw_params.ring_mask->reo_status[0];
158
break;
159
case HAL_RXDMA_MONITOR_STATUS:
160
case HAL_RXDMA_MONITOR_DST:
161
grp_mask = &ab->hw_params.ring_mask->rx_mon_status[0];
162
break;
163
case HAL_RXDMA_DST:
164
grp_mask = &ab->hw_params.ring_mask->rxdma2host[0];
165
break;
166
case HAL_RXDMA_BUF:
167
grp_mask = &ab->hw_params.ring_mask->host2rxdma[0];
168
break;
169
case HAL_RXDMA_MONITOR_BUF:
170
case HAL_TCL_DATA:
171
case HAL_TCL_CMD:
172
case HAL_REO_CMD:
173
case HAL_SW2WBM_RELEASE:
174
case HAL_WBM_IDLE_LINK:
175
case HAL_TCL_STATUS:
176
case HAL_REO_REINJECT:
177
case HAL_CE_SRC:
178
case HAL_CE_DST:
179
case HAL_CE_DST_STATUS:
180
default:
181
return -ENOENT;
182
}
183
184
return ath11k_dp_srng_find_ring_in_mask(ring_num, grp_mask);
185
}
186
187
static void ath11k_dp_srng_msi_setup(struct ath11k_base *ab,
188
struct hal_srng_params *ring_params,
189
enum hal_ring_type type, int ring_num)
190
{
191
int msi_group_number, msi_data_count;
192
u32 msi_data_start, msi_irq_start, addr_lo, addr_hi;
193
int ret;
194
195
ret = ath11k_get_user_msi_vector(ab, "DP",
196
&msi_data_count, &msi_data_start,
197
&msi_irq_start);
198
if (ret)
199
return;
200
201
msi_group_number = ath11k_dp_srng_calculate_msi_group(ab, type,
202
ring_num);
203
if (msi_group_number < 0) {
204
ath11k_dbg(ab, ATH11K_DBG_PCI,
205
"ring not part of an ext_group; ring_type: %d,ring_num %d",
206
type, ring_num);
207
ring_params->msi_addr = 0;
208
ring_params->msi_data = 0;
209
return;
210
}
211
212
if (msi_group_number > msi_data_count) {
213
ath11k_dbg(ab, ATH11K_DBG_PCI,
214
"multiple msi_groups share one msi, msi_group_num %d",
215
msi_group_number);
216
}
217
218
ath11k_get_msi_address(ab, &addr_lo, &addr_hi);
219
220
ring_params->msi_addr = addr_lo;
221
ring_params->msi_addr |= (dma_addr_t)(((uint64_t)addr_hi) << 32);
222
ring_params->msi_data = (msi_group_number % msi_data_count)
223
+ msi_data_start;
224
ring_params->flags |= HAL_SRNG_FLAGS_MSI_INTR;
225
}
226
227
int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring,
228
enum hal_ring_type type, int ring_num,
229
int mac_id, int num_entries)
230
{
231
struct hal_srng_params params = {};
232
int entry_sz = ath11k_hal_srng_get_entrysize(ab, type);
233
int max_entries = ath11k_hal_srng_get_max_entries(ab, type);
234
int ret;
235
bool cached = false;
236
237
if (max_entries < 0 || entry_sz < 0)
238
return -EINVAL;
239
240
if (num_entries > max_entries)
241
num_entries = max_entries;
242
243
ring->size = (num_entries * entry_sz) + HAL_RING_BASE_ALIGN - 1;
244
245
if (ab->hw_params.alloc_cacheable_memory) {
246
/* Allocate the reo dst and tx completion rings from cacheable memory */
247
switch (type) {
248
case HAL_REO_DST:
249
case HAL_WBM2SW_RELEASE:
250
cached = true;
251
break;
252
default:
253
cached = false;
254
}
255
}
256
257
if (cached)
258
ring->vaddr_unaligned = dma_alloc_noncoherent(ab->dev, ring->size,
259
&ring->paddr_unaligned,
260
DMA_FROM_DEVICE,
261
GFP_KERNEL);
262
else
263
ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size,
264
&ring->paddr_unaligned,
265
GFP_KERNEL);
266
267
if (!ring->vaddr_unaligned)
268
return -ENOMEM;
269
270
ring->vaddr = PTR_ALIGN(ring->vaddr_unaligned, HAL_RING_BASE_ALIGN);
271
ring->paddr = ring->paddr_unaligned + ((unsigned long)ring->vaddr -
272
(unsigned long)ring->vaddr_unaligned);
273
274
params.ring_base_vaddr = ring->vaddr;
275
params.ring_base_paddr = ring->paddr;
276
params.num_entries = num_entries;
277
ath11k_dp_srng_msi_setup(ab, &params, type, ring_num + mac_id);
278
279
switch (type) {
280
case HAL_REO_DST:
281
params.intr_batch_cntr_thres_entries =
282
HAL_SRNG_INT_BATCH_THRESHOLD_RX;
283
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
284
break;
285
case HAL_RXDMA_BUF:
286
case HAL_RXDMA_MONITOR_BUF:
287
case HAL_RXDMA_MONITOR_STATUS:
288
params.low_threshold = num_entries >> 3;
289
params.flags |= HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN;
290
params.intr_batch_cntr_thres_entries = 0;
291
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_RX;
292
break;
293
case HAL_WBM2SW_RELEASE:
294
if (ring_num < 3) {
295
params.intr_batch_cntr_thres_entries =
296
HAL_SRNG_INT_BATCH_THRESHOLD_TX;
297
params.intr_timer_thres_us =
298
HAL_SRNG_INT_TIMER_THRESHOLD_TX;
299
break;
300
}
301
/* follow through when ring_num >= 3 */
302
fallthrough;
303
case HAL_REO_EXCEPTION:
304
case HAL_REO_REINJECT:
305
case HAL_REO_CMD:
306
case HAL_REO_STATUS:
307
case HAL_TCL_DATA:
308
case HAL_TCL_CMD:
309
case HAL_TCL_STATUS:
310
case HAL_WBM_IDLE_LINK:
311
case HAL_SW2WBM_RELEASE:
312
case HAL_RXDMA_DST:
313
case HAL_RXDMA_MONITOR_DST:
314
case HAL_RXDMA_MONITOR_DESC:
315
params.intr_batch_cntr_thres_entries =
316
HAL_SRNG_INT_BATCH_THRESHOLD_OTHER;
317
params.intr_timer_thres_us = HAL_SRNG_INT_TIMER_THRESHOLD_OTHER;
318
break;
319
case HAL_RXDMA_DIR_BUF:
320
break;
321
default:
322
ath11k_warn(ab, "Not a valid ring type in dp :%d\n", type);
323
return -EINVAL;
324
}
325
326
if (cached) {
327
params.flags |= HAL_SRNG_FLAGS_CACHED;
328
ring->cached = 1;
329
}
330
331
ret = ath11k_hal_srng_setup(ab, type, ring_num, mac_id, &params);
332
if (ret < 0) {
333
ath11k_warn(ab, "failed to setup srng: %d ring_id %d\n",
334
ret, ring_num);
335
return ret;
336
}
337
338
ring->ring_id = ret;
339
340
return 0;
341
}
342
343
void ath11k_dp_stop_shadow_timers(struct ath11k_base *ab)
344
{
345
int i;
346
347
if (!ab->hw_params.supports_shadow_regs)
348
return;
349
350
for (i = 0; i < ab->hw_params.max_tx_ring; i++)
351
ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]);
352
353
ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer);
354
}
355
356
static void ath11k_dp_srng_common_cleanup(struct ath11k_base *ab)
357
{
358
struct ath11k_dp *dp = &ab->dp;
359
int i;
360
361
ath11k_dp_stop_shadow_timers(ab);
362
ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring);
363
ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring);
364
ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring);
365
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
366
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring);
367
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring);
368
}
369
ath11k_dp_srng_cleanup(ab, &dp->reo_reinject_ring);
370
ath11k_dp_srng_cleanup(ab, &dp->rx_rel_ring);
371
ath11k_dp_srng_cleanup(ab, &dp->reo_except_ring);
372
ath11k_dp_srng_cleanup(ab, &dp->reo_cmd_ring);
373
ath11k_dp_srng_cleanup(ab, &dp->reo_status_ring);
374
}
375
376
static int ath11k_dp_srng_common_setup(struct ath11k_base *ab)
377
{
378
struct ath11k_dp *dp = &ab->dp;
379
struct hal_srng *srng;
380
int i, ret;
381
u8 tcl_num, wbm_num;
382
383
ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring,
384
HAL_SW2WBM_RELEASE, 0, 0,
385
DP_WBM_RELEASE_RING_SIZE);
386
if (ret) {
387
ath11k_warn(ab, "failed to set up wbm2sw_release ring :%d\n",
388
ret);
389
goto err;
390
}
391
392
ret = ath11k_dp_srng_setup(ab, &dp->tcl_cmd_ring, HAL_TCL_CMD, 0, 0,
393
DP_TCL_CMD_RING_SIZE);
394
if (ret) {
395
ath11k_warn(ab, "failed to set up tcl_cmd ring :%d\n", ret);
396
goto err;
397
}
398
399
ret = ath11k_dp_srng_setup(ab, &dp->tcl_status_ring, HAL_TCL_STATUS,
400
0, 0, DP_TCL_STATUS_RING_SIZE);
401
if (ret) {
402
ath11k_warn(ab, "failed to set up tcl_status ring :%d\n", ret);
403
goto err;
404
}
405
406
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
407
tcl_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].tcl_ring_num;
408
wbm_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num;
409
410
ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring,
411
HAL_TCL_DATA, tcl_num, 0,
412
ab->hw_params.tx_ring_size);
413
if (ret) {
414
ath11k_warn(ab, "failed to set up tcl_data ring (%d) :%d\n",
415
i, ret);
416
goto err;
417
}
418
419
ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_comp_ring,
420
HAL_WBM2SW_RELEASE, wbm_num, 0,
421
DP_TX_COMP_RING_SIZE);
422
if (ret) {
423
ath11k_warn(ab, "failed to set up tcl_comp ring (%d) :%d\n",
424
i, ret);
425
goto err;
426
}
427
428
srng = &ab->hal.srng_list[dp->tx_ring[i].tcl_data_ring.ring_id];
429
ath11k_hal_tx_init_data_ring(ab, srng);
430
431
ath11k_dp_shadow_init_timer(ab, &dp->tx_ring_timer[i],
432
ATH11K_SHADOW_DP_TIMER_INTERVAL,
433
dp->tx_ring[i].tcl_data_ring.ring_id);
434
}
435
436
ret = ath11k_dp_srng_setup(ab, &dp->reo_reinject_ring, HAL_REO_REINJECT,
437
0, 0, DP_REO_REINJECT_RING_SIZE);
438
if (ret) {
439
ath11k_warn(ab, "failed to set up reo_reinject ring :%d\n",
440
ret);
441
goto err;
442
}
443
444
ret = ath11k_dp_srng_setup(ab, &dp->rx_rel_ring, HAL_WBM2SW_RELEASE,
445
DP_RX_RELEASE_RING_NUM, 0, DP_RX_RELEASE_RING_SIZE);
446
if (ret) {
447
ath11k_warn(ab, "failed to set up rx_rel ring :%d\n", ret);
448
goto err;
449
}
450
451
ret = ath11k_dp_srng_setup(ab, &dp->reo_except_ring, HAL_REO_EXCEPTION,
452
0, 0, DP_REO_EXCEPTION_RING_SIZE);
453
if (ret) {
454
ath11k_warn(ab, "failed to set up reo_exception ring :%d\n",
455
ret);
456
goto err;
457
}
458
459
ret = ath11k_dp_srng_setup(ab, &dp->reo_cmd_ring, HAL_REO_CMD,
460
0, 0, DP_REO_CMD_RING_SIZE);
461
if (ret) {
462
ath11k_warn(ab, "failed to set up reo_cmd ring :%d\n", ret);
463
goto err;
464
}
465
466
srng = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
467
ath11k_hal_reo_init_cmd_ring(ab, srng);
468
469
ath11k_dp_shadow_init_timer(ab, &dp->reo_cmd_timer,
470
ATH11K_SHADOW_CTRL_TIMER_INTERVAL,
471
dp->reo_cmd_ring.ring_id);
472
473
ret = ath11k_dp_srng_setup(ab, &dp->reo_status_ring, HAL_REO_STATUS,
474
0, 0, DP_REO_STATUS_RING_SIZE);
475
if (ret) {
476
ath11k_warn(ab, "failed to set up reo_status ring :%d\n", ret);
477
goto err;
478
}
479
480
/* When hash based routing of rx packet is enabled, 32 entries to map
481
* the hash values to the ring will be configured.
482
*/
483
ab->hw_params.hw_ops->reo_setup(ab);
484
485
return 0;
486
487
err:
488
ath11k_dp_srng_common_cleanup(ab);
489
490
return ret;
491
}
492
493
static void ath11k_dp_scatter_idle_link_desc_cleanup(struct ath11k_base *ab)
494
{
495
struct ath11k_dp *dp = &ab->dp;
496
struct hal_wbm_idle_scatter_list *slist = dp->scatter_list;
497
int i;
498
499
for (i = 0; i < DP_IDLE_SCATTER_BUFS_MAX; i++) {
500
if (!slist[i].vaddr)
501
continue;
502
503
dma_free_coherent(ab->dev, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX,
504
slist[i].vaddr, slist[i].paddr);
505
slist[i].vaddr = NULL;
506
}
507
}
508
509
static int ath11k_dp_scatter_idle_link_desc_setup(struct ath11k_base *ab,
510
int size,
511
u32 n_link_desc_bank,
512
u32 n_link_desc,
513
u32 last_bank_sz)
514
{
515
struct ath11k_dp *dp = &ab->dp;
516
struct dp_link_desc_bank *link_desc_banks = dp->link_desc_banks;
517
struct hal_wbm_idle_scatter_list *slist = dp->scatter_list;
518
u32 n_entries_per_buf;
519
int num_scatter_buf, scatter_idx;
520
struct hal_wbm_link_desc *scatter_buf;
521
int align_bytes, n_entries;
522
dma_addr_t paddr;
523
int rem_entries;
524
int i;
525
int ret = 0;
526
u32 end_offset;
527
528
n_entries_per_buf = HAL_WBM_IDLE_SCATTER_BUF_SIZE /
529
ath11k_hal_srng_get_entrysize(ab, HAL_WBM_IDLE_LINK);
530
num_scatter_buf = DIV_ROUND_UP(size, HAL_WBM_IDLE_SCATTER_BUF_SIZE);
531
532
if (num_scatter_buf > DP_IDLE_SCATTER_BUFS_MAX)
533
return -EINVAL;
534
535
for (i = 0; i < num_scatter_buf; i++) {
536
slist[i].vaddr = dma_alloc_coherent(ab->dev,
537
HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX,
538
&slist[i].paddr, GFP_KERNEL);
539
if (!slist[i].vaddr) {
540
ret = -ENOMEM;
541
goto err;
542
}
543
}
544
545
scatter_idx = 0;
546
scatter_buf = slist[scatter_idx].vaddr;
547
rem_entries = n_entries_per_buf;
548
549
for (i = 0; i < n_link_desc_bank; i++) {
550
#if defined(__linux__)
551
align_bytes = link_desc_banks[i].vaddr -
552
link_desc_banks[i].vaddr_unaligned;
553
#elif defined(__FreeBSD__)
554
align_bytes = (uintptr_t)link_desc_banks[i].vaddr -
555
(uintptr_t)link_desc_banks[i].vaddr_unaligned;
556
#endif
557
n_entries = (DP_LINK_DESC_ALLOC_SIZE_THRESH - align_bytes) /
558
HAL_LINK_DESC_SIZE;
559
paddr = link_desc_banks[i].paddr;
560
while (n_entries) {
561
ath11k_hal_set_link_desc_addr(scatter_buf, i, paddr);
562
n_entries--;
563
paddr += HAL_LINK_DESC_SIZE;
564
if (rem_entries) {
565
rem_entries--;
566
scatter_buf++;
567
continue;
568
}
569
570
rem_entries = n_entries_per_buf;
571
scatter_idx++;
572
scatter_buf = slist[scatter_idx].vaddr;
573
}
574
}
575
576
end_offset = (scatter_buf - slist[scatter_idx].vaddr) *
577
sizeof(struct hal_wbm_link_desc);
578
ath11k_hal_setup_link_idle_list(ab, slist, num_scatter_buf,
579
n_link_desc, end_offset);
580
581
return 0;
582
583
err:
584
ath11k_dp_scatter_idle_link_desc_cleanup(ab);
585
586
return ret;
587
}
588
589
static void
590
ath11k_dp_link_desc_bank_free(struct ath11k_base *ab,
591
struct dp_link_desc_bank *link_desc_banks)
592
{
593
int i;
594
595
for (i = 0; i < DP_LINK_DESC_BANKS_MAX; i++) {
596
if (link_desc_banks[i].vaddr_unaligned) {
597
dma_free_coherent(ab->dev,
598
link_desc_banks[i].size,
599
link_desc_banks[i].vaddr_unaligned,
600
link_desc_banks[i].paddr_unaligned);
601
link_desc_banks[i].vaddr_unaligned = NULL;
602
}
603
}
604
}
605
606
static int ath11k_dp_link_desc_bank_alloc(struct ath11k_base *ab,
607
struct dp_link_desc_bank *desc_bank,
608
int n_link_desc_bank,
609
int last_bank_sz)
610
{
611
struct ath11k_dp *dp = &ab->dp;
612
int i;
613
int ret = 0;
614
int desc_sz = DP_LINK_DESC_ALLOC_SIZE_THRESH;
615
616
for (i = 0; i < n_link_desc_bank; i++) {
617
if (i == (n_link_desc_bank - 1) && last_bank_sz)
618
desc_sz = last_bank_sz;
619
620
desc_bank[i].vaddr_unaligned =
621
dma_alloc_coherent(ab->dev, desc_sz,
622
&desc_bank[i].paddr_unaligned,
623
GFP_KERNEL);
624
if (!desc_bank[i].vaddr_unaligned) {
625
ret = -ENOMEM;
626
goto err;
627
}
628
629
desc_bank[i].vaddr = PTR_ALIGN(desc_bank[i].vaddr_unaligned,
630
HAL_LINK_DESC_ALIGN);
631
desc_bank[i].paddr = desc_bank[i].paddr_unaligned +
632
((unsigned long)desc_bank[i].vaddr -
633
(unsigned long)desc_bank[i].vaddr_unaligned);
634
desc_bank[i].size = desc_sz;
635
}
636
637
return 0;
638
639
err:
640
ath11k_dp_link_desc_bank_free(ab, dp->link_desc_banks);
641
642
return ret;
643
}
644
645
void ath11k_dp_link_desc_cleanup(struct ath11k_base *ab,
646
struct dp_link_desc_bank *desc_bank,
647
u32 ring_type, struct dp_srng *ring)
648
{
649
ath11k_dp_link_desc_bank_free(ab, desc_bank);
650
651
if (ring_type != HAL_RXDMA_MONITOR_DESC) {
652
ath11k_dp_srng_cleanup(ab, ring);
653
ath11k_dp_scatter_idle_link_desc_cleanup(ab);
654
}
655
}
656
657
static int ath11k_wbm_idle_ring_setup(struct ath11k_base *ab, u32 *n_link_desc)
658
{
659
struct ath11k_dp *dp = &ab->dp;
660
u32 n_mpdu_link_desc, n_mpdu_queue_desc;
661
u32 n_tx_msdu_link_desc, n_rx_msdu_link_desc;
662
int ret = 0;
663
664
n_mpdu_link_desc = (DP_NUM_TIDS_MAX * DP_AVG_MPDUS_PER_TID_MAX) /
665
HAL_NUM_MPDUS_PER_LINK_DESC;
666
667
n_mpdu_queue_desc = n_mpdu_link_desc /
668
HAL_NUM_MPDU_LINKS_PER_QUEUE_DESC;
669
670
n_tx_msdu_link_desc = (DP_NUM_TIDS_MAX * DP_AVG_FLOWS_PER_TID *
671
DP_AVG_MSDUS_PER_FLOW) /
672
HAL_NUM_TX_MSDUS_PER_LINK_DESC;
673
674
n_rx_msdu_link_desc = (DP_NUM_TIDS_MAX * DP_AVG_MPDUS_PER_TID_MAX *
675
DP_AVG_MSDUS_PER_MPDU) /
676
HAL_NUM_RX_MSDUS_PER_LINK_DESC;
677
678
*n_link_desc = n_mpdu_link_desc + n_mpdu_queue_desc +
679
n_tx_msdu_link_desc + n_rx_msdu_link_desc;
680
681
if (*n_link_desc & (*n_link_desc - 1))
682
*n_link_desc = 1 << fls(*n_link_desc);
683
684
ret = ath11k_dp_srng_setup(ab, &dp->wbm_idle_ring,
685
HAL_WBM_IDLE_LINK, 0, 0, *n_link_desc);
686
if (ret) {
687
ath11k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret);
688
return ret;
689
}
690
return ret;
691
}
692
693
int ath11k_dp_link_desc_setup(struct ath11k_base *ab,
694
struct dp_link_desc_bank *link_desc_banks,
695
u32 ring_type, struct hal_srng *srng,
696
u32 n_link_desc)
697
{
698
u32 tot_mem_sz;
699
u32 n_link_desc_bank, last_bank_sz;
700
u32 entry_sz, align_bytes, n_entries;
701
u32 paddr;
702
u32 *desc;
703
int i, ret;
704
705
tot_mem_sz = n_link_desc * HAL_LINK_DESC_SIZE;
706
tot_mem_sz += HAL_LINK_DESC_ALIGN;
707
708
if (tot_mem_sz <= DP_LINK_DESC_ALLOC_SIZE_THRESH) {
709
n_link_desc_bank = 1;
710
last_bank_sz = tot_mem_sz;
711
} else {
712
n_link_desc_bank = tot_mem_sz /
713
(DP_LINK_DESC_ALLOC_SIZE_THRESH -
714
HAL_LINK_DESC_ALIGN);
715
last_bank_sz = tot_mem_sz %
716
(DP_LINK_DESC_ALLOC_SIZE_THRESH -
717
HAL_LINK_DESC_ALIGN);
718
719
if (last_bank_sz)
720
n_link_desc_bank += 1;
721
}
722
723
if (n_link_desc_bank > DP_LINK_DESC_BANKS_MAX)
724
return -EINVAL;
725
726
ret = ath11k_dp_link_desc_bank_alloc(ab, link_desc_banks,
727
n_link_desc_bank, last_bank_sz);
728
if (ret)
729
return ret;
730
731
/* Setup link desc idle list for HW internal usage */
732
entry_sz = ath11k_hal_srng_get_entrysize(ab, ring_type);
733
tot_mem_sz = entry_sz * n_link_desc;
734
735
/* Setup scatter desc list when the total memory requirement is more */
736
if (tot_mem_sz > DP_LINK_DESC_ALLOC_SIZE_THRESH &&
737
ring_type != HAL_RXDMA_MONITOR_DESC) {
738
ret = ath11k_dp_scatter_idle_link_desc_setup(ab, tot_mem_sz,
739
n_link_desc_bank,
740
n_link_desc,
741
last_bank_sz);
742
if (ret) {
743
ath11k_warn(ab, "failed to setup scatting idle list descriptor :%d\n",
744
ret);
745
goto fail_desc_bank_free;
746
}
747
748
return 0;
749
}
750
751
spin_lock_bh(&srng->lock);
752
753
ath11k_hal_srng_access_begin(ab, srng);
754
755
for (i = 0; i < n_link_desc_bank; i++) {
756
#if defined(__linux__)
757
align_bytes = link_desc_banks[i].vaddr -
758
link_desc_banks[i].vaddr_unaligned;
759
#elif defined(__FreeBSD__)
760
align_bytes = (uintptr_t)link_desc_banks[i].vaddr -
761
(uintptr_t)link_desc_banks[i].vaddr_unaligned;
762
#endif
763
n_entries = (link_desc_banks[i].size - align_bytes) /
764
HAL_LINK_DESC_SIZE;
765
paddr = link_desc_banks[i].paddr;
766
while (n_entries &&
767
(desc = ath11k_hal_srng_src_get_next_entry(ab, srng))) {
768
ath11k_hal_set_link_desc_addr((struct hal_wbm_link_desc *)desc,
769
i, paddr);
770
n_entries--;
771
paddr += HAL_LINK_DESC_SIZE;
772
}
773
}
774
775
ath11k_hal_srng_access_end(ab, srng);
776
777
spin_unlock_bh(&srng->lock);
778
779
return 0;
780
781
fail_desc_bank_free:
782
ath11k_dp_link_desc_bank_free(ab, link_desc_banks);
783
784
return ret;
785
}
786
787
int ath11k_dp_service_srng(struct ath11k_base *ab,
788
struct ath11k_ext_irq_grp *irq_grp,
789
int budget)
790
{
791
struct napi_struct *napi = &irq_grp->napi;
792
const struct ath11k_hw_hal_params *hal_params;
793
int grp_id = irq_grp->grp_id;
794
int work_done = 0;
795
int i, j;
796
int tot_work_done = 0;
797
798
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
799
if (BIT(ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num) &
800
ab->hw_params.ring_mask->tx[grp_id])
801
ath11k_dp_tx_completion_handler(ab, i);
802
}
803
804
if (ab->hw_params.ring_mask->rx_err[grp_id]) {
805
work_done = ath11k_dp_process_rx_err(ab, napi, budget);
806
budget -= work_done;
807
tot_work_done += work_done;
808
if (budget <= 0)
809
goto done;
810
}
811
812
if (ab->hw_params.ring_mask->rx_wbm_rel[grp_id]) {
813
work_done = ath11k_dp_rx_process_wbm_err(ab,
814
napi,
815
budget);
816
budget -= work_done;
817
tot_work_done += work_done;
818
819
if (budget <= 0)
820
goto done;
821
}
822
823
if (ab->hw_params.ring_mask->rx[grp_id]) {
824
i = fls(ab->hw_params.ring_mask->rx[grp_id]) - 1;
825
work_done = ath11k_dp_process_rx(ab, i, napi,
826
budget);
827
budget -= work_done;
828
tot_work_done += work_done;
829
if (budget <= 0)
830
goto done;
831
}
832
833
if (ab->hw_params.ring_mask->rx_mon_status[grp_id]) {
834
for (i = 0; i < ab->num_radios; i++) {
835
for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
836
int id = i * ab->hw_params.num_rxdma_per_pdev + j;
837
838
if (ab->hw_params.ring_mask->rx_mon_status[grp_id] &
839
BIT(id)) {
840
work_done =
841
ath11k_dp_rx_process_mon_rings(ab,
842
id,
843
napi, budget);
844
budget -= work_done;
845
tot_work_done += work_done;
846
847
if (budget <= 0)
848
goto done;
849
}
850
}
851
}
852
}
853
854
if (ab->hw_params.ring_mask->reo_status[grp_id])
855
ath11k_dp_process_reo_status(ab);
856
857
for (i = 0; i < ab->num_radios; i++) {
858
for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
859
int id = i * ab->hw_params.num_rxdma_per_pdev + j;
860
861
if (ab->hw_params.ring_mask->rxdma2host[grp_id] & BIT(id)) {
862
work_done = ath11k_dp_process_rxdma_err(ab, id, budget);
863
budget -= work_done;
864
tot_work_done += work_done;
865
}
866
867
if (budget <= 0)
868
goto done;
869
870
if (ab->hw_params.ring_mask->host2rxdma[grp_id] & BIT(id)) {
871
struct ath11k *ar = ath11k_ab_to_ar(ab, id);
872
struct ath11k_pdev_dp *dp = &ar->dp;
873
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
874
875
hal_params = ab->hw_params.hal_params;
876
ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0,
877
hal_params->rx_buf_rbm);
878
}
879
}
880
}
881
/* TODO: Implement handler for other interrupts */
882
883
done:
884
return tot_work_done;
885
}
886
EXPORT_SYMBOL(ath11k_dp_service_srng);
887
888
void ath11k_dp_pdev_free(struct ath11k_base *ab)
889
{
890
struct ath11k *ar;
891
int i;
892
893
timer_delete_sync(&ab->mon_reap_timer);
894
895
for (i = 0; i < ab->num_radios; i++) {
896
ar = ab->pdevs[i].ar;
897
ath11k_dp_rx_pdev_free(ab, i);
898
ath11k_debugfs_unregister(ar);
899
ath11k_dp_rx_pdev_mon_detach(ar);
900
}
901
}
902
903
void ath11k_dp_pdev_pre_alloc(struct ath11k_base *ab)
904
{
905
struct ath11k *ar;
906
struct ath11k_pdev_dp *dp;
907
int i;
908
int j;
909
910
for (i = 0; i < ab->num_radios; i++) {
911
ar = ab->pdevs[i].ar;
912
dp = &ar->dp;
913
dp->mac_id = i;
914
idr_init(&dp->rx_refill_buf_ring.bufs_idr);
915
spin_lock_init(&dp->rx_refill_buf_ring.idr_lock);
916
atomic_set(&dp->num_tx_pending, 0);
917
init_waitqueue_head(&dp->tx_empty_waitq);
918
for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
919
idr_init(&dp->rx_mon_status_refill_ring[j].bufs_idr);
920
spin_lock_init(&dp->rx_mon_status_refill_ring[j].idr_lock);
921
}
922
idr_init(&dp->rxdma_mon_buf_ring.bufs_idr);
923
spin_lock_init(&dp->rxdma_mon_buf_ring.idr_lock);
924
}
925
}
926
927
int ath11k_dp_pdev_alloc(struct ath11k_base *ab)
928
{
929
struct ath11k *ar;
930
int ret;
931
int i;
932
933
/* TODO:Per-pdev rx ring unlike tx ring which is mapped to different AC's */
934
for (i = 0; i < ab->num_radios; i++) {
935
ar = ab->pdevs[i].ar;
936
ret = ath11k_dp_rx_pdev_alloc(ab, i);
937
if (ret) {
938
ath11k_warn(ab, "failed to allocate pdev rx for pdev_id :%d\n",
939
i);
940
goto err;
941
}
942
ret = ath11k_dp_rx_pdev_mon_attach(ar);
943
if (ret) {
944
ath11k_warn(ab, "failed to initialize mon pdev %d\n",
945
i);
946
goto err;
947
}
948
}
949
950
return 0;
951
952
err:
953
ath11k_dp_pdev_free(ab);
954
955
return ret;
956
}
957
958
int ath11k_dp_htt_connect(struct ath11k_dp *dp)
959
{
960
struct ath11k_htc_svc_conn_req conn_req;
961
struct ath11k_htc_svc_conn_resp conn_resp;
962
int status;
963
964
memset(&conn_req, 0, sizeof(conn_req));
965
memset(&conn_resp, 0, sizeof(conn_resp));
966
967
conn_req.ep_ops.ep_tx_complete = ath11k_dp_htt_htc_tx_complete;
968
conn_req.ep_ops.ep_rx_complete = ath11k_dp_htt_htc_t2h_msg_handler;
969
970
/* connect to control service */
971
conn_req.service_id = ATH11K_HTC_SVC_ID_HTT_DATA_MSG;
972
973
status = ath11k_htc_connect_service(&dp->ab->htc, &conn_req,
974
&conn_resp);
975
976
if (status)
977
return status;
978
979
dp->eid = conn_resp.eid;
980
981
return 0;
982
}
983
984
static void ath11k_dp_update_vdev_search(struct ath11k_vif *arvif)
985
{
986
/* When v2_map_support is true:for STA mode, enable address
987
* search index, tcl uses ast_hash value in the descriptor.
988
* When v2_map_support is false: for STA mode, don't enable
989
* address search index.
990
*/
991
switch (arvif->vdev_type) {
992
case WMI_VDEV_TYPE_STA:
993
if (arvif->ar->ab->hw_params.htt_peer_map_v2) {
994
arvif->hal_addr_search_flags = HAL_TX_ADDRX_EN;
995
arvif->search_type = HAL_TX_ADDR_SEARCH_INDEX;
996
} else {
997
arvif->hal_addr_search_flags = HAL_TX_ADDRY_EN;
998
arvif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT;
999
}
1000
break;
1001
case WMI_VDEV_TYPE_AP:
1002
case WMI_VDEV_TYPE_IBSS:
1003
arvif->hal_addr_search_flags = HAL_TX_ADDRX_EN;
1004
arvif->search_type = HAL_TX_ADDR_SEARCH_DEFAULT;
1005
break;
1006
case WMI_VDEV_TYPE_MONITOR:
1007
default:
1008
return;
1009
}
1010
}
1011
1012
void ath11k_dp_vdev_tx_attach(struct ath11k *ar, struct ath11k_vif *arvif)
1013
{
1014
arvif->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 1) |
1015
FIELD_PREP(HTT_TCL_META_DATA_VDEV_ID,
1016
arvif->vdev_id) |
1017
FIELD_PREP(HTT_TCL_META_DATA_PDEV_ID,
1018
ar->pdev->pdev_id);
1019
1020
/* set HTT extension valid bit to 0 by default */
1021
arvif->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT;
1022
1023
ath11k_dp_update_vdev_search(arvif);
1024
}
1025
1026
static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx)
1027
{
1028
struct ath11k_base *ab = ctx;
1029
struct sk_buff *msdu = skb;
1030
1031
dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,
1032
DMA_TO_DEVICE);
1033
1034
dev_kfree_skb_any(msdu);
1035
1036
return 0;
1037
}
1038
1039
void ath11k_dp_free(struct ath11k_base *ab)
1040
{
1041
struct ath11k_dp *dp = &ab->dp;
1042
int i;
1043
1044
ath11k_dp_link_desc_cleanup(ab, dp->link_desc_banks,
1045
HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring);
1046
1047
ath11k_dp_srng_common_cleanup(ab);
1048
1049
ath11k_dp_reo_cmd_list_cleanup(ab);
1050
1051
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
1052
spin_lock_bh(&dp->tx_ring[i].tx_idr_lock);
1053
idr_for_each(&dp->tx_ring[i].txbuf_idr,
1054
ath11k_dp_tx_pending_cleanup, ab);
1055
idr_destroy(&dp->tx_ring[i].txbuf_idr);
1056
spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock);
1057
kfree(dp->tx_ring[i].tx_status);
1058
}
1059
1060
/* Deinit any SOC level resource */
1061
}
1062
1063
int ath11k_dp_alloc(struct ath11k_base *ab)
1064
{
1065
struct ath11k_dp *dp = &ab->dp;
1066
struct hal_srng *srng = NULL;
1067
size_t size = 0;
1068
u32 n_link_desc = 0;
1069
int ret;
1070
int i;
1071
1072
dp->ab = ab;
1073
1074
INIT_LIST_HEAD(&dp->reo_cmd_list);
1075
INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list);
1076
INIT_LIST_HEAD(&dp->dp_full_mon_mpdu_list);
1077
spin_lock_init(&dp->reo_cmd_lock);
1078
1079
dp->reo_cmd_cache_flush_count = 0;
1080
1081
ret = ath11k_wbm_idle_ring_setup(ab, &n_link_desc);
1082
if (ret) {
1083
ath11k_warn(ab, "failed to setup wbm_idle_ring: %d\n", ret);
1084
return ret;
1085
}
1086
1087
srng = &ab->hal.srng_list[dp->wbm_idle_ring.ring_id];
1088
1089
ret = ath11k_dp_link_desc_setup(ab, dp->link_desc_banks,
1090
HAL_WBM_IDLE_LINK, srng, n_link_desc);
1091
if (ret) {
1092
ath11k_warn(ab, "failed to setup link desc: %d\n", ret);
1093
return ret;
1094
}
1095
1096
ret = ath11k_dp_srng_common_setup(ab);
1097
if (ret)
1098
goto fail_link_desc_cleanup;
1099
1100
size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE;
1101
1102
for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
1103
idr_init(&dp->tx_ring[i].txbuf_idr);
1104
spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
1105
dp->tx_ring[i].tcl_data_ring_id = i;
1106
1107
dp->tx_ring[i].tx_status_head = 0;
1108
dp->tx_ring[i].tx_status_tail = DP_TX_COMP_RING_SIZE - 1;
1109
dp->tx_ring[i].tx_status = kmalloc(size, GFP_KERNEL);
1110
if (!dp->tx_ring[i].tx_status) {
1111
ret = -ENOMEM;
1112
goto fail_cmn_srng_cleanup;
1113
}
1114
}
1115
1116
for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++)
1117
ath11k_hal_tx_set_dscp_tid_map(ab, i);
1118
1119
/* Init any SOC level resource for DP */
1120
1121
return 0;
1122
1123
fail_cmn_srng_cleanup:
1124
ath11k_dp_srng_common_cleanup(ab);
1125
1126
fail_link_desc_cleanup:
1127
ath11k_dp_link_desc_cleanup(ab, dp->link_desc_banks,
1128
HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring);
1129
1130
return ret;
1131
}
1132
1133
static void ath11k_dp_shadow_timer_handler(struct timer_list *t)
1134
{
1135
struct ath11k_hp_update_timer *update_timer = timer_container_of(update_timer,
1136
t,
1137
timer);
1138
struct ath11k_base *ab = update_timer->ab;
1139
struct hal_srng *srng = &ab->hal.srng_list[update_timer->ring_id];
1140
1141
spin_lock_bh(&srng->lock);
1142
1143
/* when the timer is fired, the handler checks whether there
1144
* are new TX happened. The handler updates HP only when there
1145
* are no TX operations during the timeout interval, and stop
1146
* the timer. Timer will be started again when TX happens again.
1147
*/
1148
if (update_timer->timer_tx_num != update_timer->tx_num) {
1149
update_timer->timer_tx_num = update_timer->tx_num;
1150
mod_timer(&update_timer->timer, jiffies +
1151
msecs_to_jiffies(update_timer->interval));
1152
} else {
1153
update_timer->started = false;
1154
ath11k_hal_srng_shadow_update_hp_tp(ab, srng);
1155
}
1156
1157
spin_unlock_bh(&srng->lock);
1158
}
1159
1160
void ath11k_dp_shadow_start_timer(struct ath11k_base *ab,
1161
struct hal_srng *srng,
1162
struct ath11k_hp_update_timer *update_timer)
1163
{
1164
lockdep_assert_held(&srng->lock);
1165
1166
if (!ab->hw_params.supports_shadow_regs)
1167
return;
1168
1169
update_timer->tx_num++;
1170
1171
if (update_timer->started)
1172
return;
1173
1174
update_timer->started = true;
1175
update_timer->timer_tx_num = update_timer->tx_num;
1176
mod_timer(&update_timer->timer, jiffies +
1177
msecs_to_jiffies(update_timer->interval));
1178
}
1179
1180
void ath11k_dp_shadow_stop_timer(struct ath11k_base *ab,
1181
struct ath11k_hp_update_timer *update_timer)
1182
{
1183
if (!ab->hw_params.supports_shadow_regs)
1184
return;
1185
1186
if (!update_timer->init)
1187
return;
1188
1189
timer_delete_sync(&update_timer->timer);
1190
}
1191
1192
void ath11k_dp_shadow_init_timer(struct ath11k_base *ab,
1193
struct ath11k_hp_update_timer *update_timer,
1194
u32 interval, u32 ring_id)
1195
{
1196
if (!ab->hw_params.supports_shadow_regs)
1197
return;
1198
1199
update_timer->tx_num = 0;
1200
update_timer->timer_tx_num = 0;
1201
update_timer->ab = ab;
1202
update_timer->ring_id = ring_id;
1203
update_timer->interval = interval;
1204
update_timer->init = true;
1205
timer_setup(&update_timer->timer,
1206
ath11k_dp_shadow_timer_handler, 0);
1207
}
1208
1209