1*60bac4d6SBjoern A. Zeeb // SPDX-License-Identifier: BSD-3-Clause-Clear
2*60bac4d6SBjoern A. Zeeb /*
3*60bac4d6SBjoern A. Zeeb * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4*60bac4d6SBjoern A. Zeeb * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5*60bac4d6SBjoern A. Zeeb */
6*60bac4d6SBjoern A. Zeeb #include "../core.h"
7*60bac4d6SBjoern A. Zeeb #include "../debug.h"
8*60bac4d6SBjoern A. Zeeb #include "../dp_rx.h"
9*60bac4d6SBjoern A. Zeeb #include "../dp_tx.h"
10*60bac4d6SBjoern A. Zeeb #include "hal_desc.h"
11*60bac4d6SBjoern A. Zeeb #include "../dp_mon.h"
12*60bac4d6SBjoern A. Zeeb #include "dp_mon.h"
13*60bac4d6SBjoern A. Zeeb #include "../dp_cmn.h"
14*60bac4d6SBjoern A. Zeeb #include "dp_rx.h"
15*60bac4d6SBjoern A. Zeeb #include "dp.h"
16*60bac4d6SBjoern A. Zeeb #include "dp_tx.h"
17*60bac4d6SBjoern A. Zeeb #include "hal.h"
18*60bac4d6SBjoern A. Zeeb
ath12k_wifi7_dp_service_srng(struct ath12k_dp * dp,struct ath12k_ext_irq_grp * irq_grp,int budget)19*60bac4d6SBjoern A. Zeeb static int ath12k_wifi7_dp_service_srng(struct ath12k_dp *dp,
20*60bac4d6SBjoern A. Zeeb struct ath12k_ext_irq_grp *irq_grp,
21*60bac4d6SBjoern A. Zeeb int budget)
22*60bac4d6SBjoern A. Zeeb {
23*60bac4d6SBjoern A. Zeeb struct napi_struct *napi = &irq_grp->napi;
24*60bac4d6SBjoern A. Zeeb int grp_id = irq_grp->grp_id;
25*60bac4d6SBjoern A. Zeeb int work_done = 0;
26*60bac4d6SBjoern A. Zeeb int i = 0, j;
27*60bac4d6SBjoern A. Zeeb int tot_work_done = 0;
28*60bac4d6SBjoern A. Zeeb enum dp_monitor_mode monitor_mode;
29*60bac4d6SBjoern A. Zeeb u8 ring_mask;
30*60bac4d6SBjoern A. Zeeb
31*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->tx[grp_id]) {
32*60bac4d6SBjoern A. Zeeb i = fls(dp->hw_params->ring_mask->tx[grp_id]) - 1;
33*60bac4d6SBjoern A. Zeeb ath12k_wifi7_dp_tx_completion_handler(dp, i);
34*60bac4d6SBjoern A. Zeeb }
35*60bac4d6SBjoern A. Zeeb
36*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->rx_err[grp_id]) {
37*60bac4d6SBjoern A. Zeeb work_done = ath12k_wifi7_dp_rx_process_err(dp, napi, budget);
38*60bac4d6SBjoern A. Zeeb budget -= work_done;
39*60bac4d6SBjoern A. Zeeb tot_work_done += work_done;
40*60bac4d6SBjoern A. Zeeb if (budget <= 0)
41*60bac4d6SBjoern A. Zeeb goto done;
42*60bac4d6SBjoern A. Zeeb }
43*60bac4d6SBjoern A. Zeeb
44*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->rx_wbm_rel[grp_id]) {
45*60bac4d6SBjoern A. Zeeb work_done = ath12k_wifi7_dp_rx_process_wbm_err(dp, napi, budget);
46*60bac4d6SBjoern A. Zeeb budget -= work_done;
47*60bac4d6SBjoern A. Zeeb tot_work_done += work_done;
48*60bac4d6SBjoern A. Zeeb
49*60bac4d6SBjoern A. Zeeb if (budget <= 0)
50*60bac4d6SBjoern A. Zeeb goto done;
51*60bac4d6SBjoern A. Zeeb }
52*60bac4d6SBjoern A. Zeeb
53*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->rx[grp_id]) {
54*60bac4d6SBjoern A. Zeeb i = fls(dp->hw_params->ring_mask->rx[grp_id]) - 1;
55*60bac4d6SBjoern A. Zeeb work_done = ath12k_wifi7_dp_rx_process(dp, i, napi, budget);
56*60bac4d6SBjoern A. Zeeb budget -= work_done;
57*60bac4d6SBjoern A. Zeeb tot_work_done += work_done;
58*60bac4d6SBjoern A. Zeeb if (budget <= 0)
59*60bac4d6SBjoern A. Zeeb goto done;
60*60bac4d6SBjoern A. Zeeb }
61*60bac4d6SBjoern A. Zeeb
62*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->rx_mon_status[grp_id]) {
63*60bac4d6SBjoern A. Zeeb ring_mask = dp->hw_params->ring_mask->rx_mon_status[grp_id];
64*60bac4d6SBjoern A. Zeeb for (i = 0; i < dp->ab->num_radios; i++) {
65*60bac4d6SBjoern A. Zeeb for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) {
66*60bac4d6SBjoern A. Zeeb int id = i * dp->hw_params->num_rxdma_per_pdev + j;
67*60bac4d6SBjoern A. Zeeb
68*60bac4d6SBjoern A. Zeeb if (ring_mask & BIT(id)) {
69*60bac4d6SBjoern A. Zeeb work_done =
70*60bac4d6SBjoern A. Zeeb ath12k_wifi7_dp_mon_process_ring(dp, id, napi,
71*60bac4d6SBjoern A. Zeeb budget,
72*60bac4d6SBjoern A. Zeeb 0);
73*60bac4d6SBjoern A. Zeeb budget -= work_done;
74*60bac4d6SBjoern A. Zeeb tot_work_done += work_done;
75*60bac4d6SBjoern A. Zeeb if (budget <= 0)
76*60bac4d6SBjoern A. Zeeb goto done;
77*60bac4d6SBjoern A. Zeeb }
78*60bac4d6SBjoern A. Zeeb }
79*60bac4d6SBjoern A. Zeeb }
80*60bac4d6SBjoern A. Zeeb }
81*60bac4d6SBjoern A. Zeeb
82*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->rx_mon_dest[grp_id]) {
83*60bac4d6SBjoern A. Zeeb monitor_mode = ATH12K_DP_RX_MONITOR_MODE;
84*60bac4d6SBjoern A. Zeeb ring_mask = dp->hw_params->ring_mask->rx_mon_dest[grp_id];
85*60bac4d6SBjoern A. Zeeb for (i = 0; i < dp->ab->num_radios; i++) {
86*60bac4d6SBjoern A. Zeeb for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) {
87*60bac4d6SBjoern A. Zeeb int id = i * dp->hw_params->num_rxdma_per_pdev + j;
88*60bac4d6SBjoern A. Zeeb
89*60bac4d6SBjoern A. Zeeb if (ring_mask & BIT(id)) {
90*60bac4d6SBjoern A. Zeeb work_done =
91*60bac4d6SBjoern A. Zeeb ath12k_wifi7_dp_mon_process_ring(dp, id, napi,
92*60bac4d6SBjoern A. Zeeb budget,
93*60bac4d6SBjoern A. Zeeb monitor_mode);
94*60bac4d6SBjoern A. Zeeb budget -= work_done;
95*60bac4d6SBjoern A. Zeeb tot_work_done += work_done;
96*60bac4d6SBjoern A. Zeeb
97*60bac4d6SBjoern A. Zeeb if (budget <= 0)
98*60bac4d6SBjoern A. Zeeb goto done;
99*60bac4d6SBjoern A. Zeeb }
100*60bac4d6SBjoern A. Zeeb }
101*60bac4d6SBjoern A. Zeeb }
102*60bac4d6SBjoern A. Zeeb }
103*60bac4d6SBjoern A. Zeeb
104*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->tx_mon_dest[grp_id]) {
105*60bac4d6SBjoern A. Zeeb monitor_mode = ATH12K_DP_TX_MONITOR_MODE;
106*60bac4d6SBjoern A. Zeeb ring_mask = dp->hw_params->ring_mask->tx_mon_dest[grp_id];
107*60bac4d6SBjoern A. Zeeb for (i = 0; i < dp->ab->num_radios; i++) {
108*60bac4d6SBjoern A. Zeeb for (j = 0; j < dp->hw_params->num_rxdma_per_pdev; j++) {
109*60bac4d6SBjoern A. Zeeb int id = i * dp->hw_params->num_rxdma_per_pdev + j;
110*60bac4d6SBjoern A. Zeeb
111*60bac4d6SBjoern A. Zeeb if (ring_mask & BIT(id)) {
112*60bac4d6SBjoern A. Zeeb work_done =
113*60bac4d6SBjoern A. Zeeb ath12k_wifi7_dp_mon_process_ring(dp, id,
114*60bac4d6SBjoern A. Zeeb napi, budget,
115*60bac4d6SBjoern A. Zeeb monitor_mode);
116*60bac4d6SBjoern A. Zeeb budget -= work_done;
117*60bac4d6SBjoern A. Zeeb tot_work_done += work_done;
118*60bac4d6SBjoern A. Zeeb
119*60bac4d6SBjoern A. Zeeb if (budget <= 0)
120*60bac4d6SBjoern A. Zeeb goto done;
121*60bac4d6SBjoern A. Zeeb }
122*60bac4d6SBjoern A. Zeeb }
123*60bac4d6SBjoern A. Zeeb }
124*60bac4d6SBjoern A. Zeeb }
125*60bac4d6SBjoern A. Zeeb
126*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->reo_status[grp_id])
127*60bac4d6SBjoern A. Zeeb ath12k_wifi7_dp_rx_process_reo_status(dp);
128*60bac4d6SBjoern A. Zeeb
129*60bac4d6SBjoern A. Zeeb if (dp->hw_params->ring_mask->host2rxdma[grp_id]) {
130*60bac4d6SBjoern A. Zeeb struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
131*60bac4d6SBjoern A. Zeeb LIST_HEAD(list);
132*60bac4d6SBjoern A. Zeeb
133*60bac4d6SBjoern A. Zeeb ath12k_dp_rx_bufs_replenish(dp, rx_ring, &list, 0);
134*60bac4d6SBjoern A. Zeeb }
135*60bac4d6SBjoern A. Zeeb
136*60bac4d6SBjoern A. Zeeb /* TODO: Implement handler for other interrupts */
137*60bac4d6SBjoern A. Zeeb
138*60bac4d6SBjoern A. Zeeb done:
139*60bac4d6SBjoern A. Zeeb return tot_work_done;
140*60bac4d6SBjoern A. Zeeb }
141*60bac4d6SBjoern A. Zeeb
142*60bac4d6SBjoern A. Zeeb static struct ath12k_dp_arch_ops ath12k_wifi7_dp_arch_ops = {
143*60bac4d6SBjoern A. Zeeb .service_srng = ath12k_wifi7_dp_service_srng,
144*60bac4d6SBjoern A. Zeeb .tx_get_vdev_bank_config = ath12k_wifi7_dp_tx_get_vdev_bank_config,
145*60bac4d6SBjoern A. Zeeb .reo_cmd_send = ath12k_wifi7_dp_reo_cmd_send,
146*60bac4d6SBjoern A. Zeeb .setup_pn_check_reo_cmd = ath12k_wifi7_dp_setup_pn_check_reo_cmd,
147*60bac4d6SBjoern A. Zeeb .rx_peer_tid_delete = ath12k_wifi7_dp_rx_peer_tid_delete,
148*60bac4d6SBjoern A. Zeeb .reo_cache_flush = ath12k_wifi7_dp_reo_cache_flush,
149*60bac4d6SBjoern A. Zeeb .rx_link_desc_return = ath12k_wifi7_dp_rx_link_desc_return,
150*60bac4d6SBjoern A. Zeeb .rx_frags_cleanup = ath12k_wifi7_dp_rx_frags_cleanup,
151*60bac4d6SBjoern A. Zeeb .peer_rx_tid_reo_update = ath12k_wifi7_peer_rx_tid_reo_update,
152*60bac4d6SBjoern A. Zeeb .rx_assign_reoq = ath12k_wifi7_dp_rx_assign_reoq,
153*60bac4d6SBjoern A. Zeeb .peer_rx_tid_qref_setup = ath12k_wifi7_peer_rx_tid_qref_setup,
154*60bac4d6SBjoern A. Zeeb .peer_rx_tid_qref_reset = ath12k_wifi7_peer_rx_tid_qref_reset,
155*60bac4d6SBjoern A. Zeeb .rx_tid_delete_handler = ath12k_wifi7_dp_rx_tid_delete_handler,
156*60bac4d6SBjoern A. Zeeb };
157*60bac4d6SBjoern A. Zeeb
158*60bac4d6SBjoern A. Zeeb /* TODO: remove export once this file is built with wifi7 ko */
ath12k_wifi7_dp_device_alloc(struct ath12k_base * ab)159*60bac4d6SBjoern A. Zeeb struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab)
160*60bac4d6SBjoern A. Zeeb {
161*60bac4d6SBjoern A. Zeeb struct ath12k_dp *dp;
162*60bac4d6SBjoern A. Zeeb
163*60bac4d6SBjoern A. Zeeb /* TODO: align dp later if cache alignment becomes a bottleneck */
164*60bac4d6SBjoern A. Zeeb dp = kzalloc_obj(*dp);
165*60bac4d6SBjoern A. Zeeb if (!dp)
166*60bac4d6SBjoern A. Zeeb return NULL;
167*60bac4d6SBjoern A. Zeeb
168*60bac4d6SBjoern A. Zeeb dp->ab = ab;
169*60bac4d6SBjoern A. Zeeb dp->dev = ab->dev;
170*60bac4d6SBjoern A. Zeeb dp->hw_params = ab->hw_params;
171*60bac4d6SBjoern A. Zeeb dp->hal = &ab->hal;
172*60bac4d6SBjoern A. Zeeb
173*60bac4d6SBjoern A. Zeeb dp->ops = &ath12k_wifi7_dp_arch_ops;
174*60bac4d6SBjoern A. Zeeb
175*60bac4d6SBjoern A. Zeeb return dp;
176*60bac4d6SBjoern A. Zeeb }
177*60bac4d6SBjoern A. Zeeb
ath12k_wifi7_dp_device_free(struct ath12k_dp * dp)178*60bac4d6SBjoern A. Zeeb void ath12k_wifi7_dp_device_free(struct ath12k_dp *dp)
179*60bac4d6SBjoern A. Zeeb {
180*60bac4d6SBjoern A. Zeeb kfree(dp);
181*60bac4d6SBjoern A. Zeeb }
182