1 | // SPDX-License-Identifier: BSD-3-Clause-Clear |
2 | /* |
3 | * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. |
4 | * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. |
5 | */ |
6 | |
7 | #include "debug.h" |
8 | #include "hal.h" |
9 | #include "hal_tx.h" |
10 | #include "hal_rx.h" |
11 | #include "hal_desc.h" |
12 | #include "hif.h" |
13 | |
14 | static void ath12k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, |
15 | u8 owner, u8 buffer_type, u32 magic) |
16 | { |
17 | hdr->info0 = le32_encode_bits(v: owner, HAL_DESC_HDR_INFO0_OWNER) | |
18 | le32_encode_bits(v: buffer_type, HAL_DESC_HDR_INFO0_BUF_TYPE); |
19 | |
20 | /* Magic pattern in reserved bits for debugging */ |
21 | hdr->info0 |= le32_encode_bits(v: magic, HAL_DESC_HDR_INFO0_DBG_RESERVED); |
22 | } |
23 | |
24 | static int ath12k_hal_reo_cmd_queue_stats(struct hal_tlv_64_hdr *tlv, |
25 | struct ath12k_hal_reo_cmd *cmd) |
26 | { |
27 | struct hal_reo_get_queue_stats *desc; |
28 | |
29 | tlv->tl = u32_encode_bits(v: HAL_REO_GET_QUEUE_STATS, HAL_TLV_HDR_TAG) | |
30 | u32_encode_bits(v: sizeof(*desc), HAL_TLV_HDR_LEN); |
31 | |
32 | desc = (struct hal_reo_get_queue_stats *)tlv->value; |
33 | memset_startat(desc, 0, queue_addr_lo); |
34 | |
35 | desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); |
36 | if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) |
37 | desc->cmd.info0 |= cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); |
38 | |
39 | desc->queue_addr_lo = cpu_to_le32(cmd->addr_lo); |
40 | desc->info0 = le32_encode_bits(v: cmd->addr_hi, |
41 | HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI); |
42 | if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR) |
43 | desc->info0 |= cpu_to_le32(HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS); |
44 | |
45 | return le32_get_bits(v: desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); |
46 | } |
47 | |
48 | static int ath12k_hal_reo_cmd_flush_cache(struct ath12k_hal *hal, |
49 | struct hal_tlv_64_hdr *tlv, |
50 | struct ath12k_hal_reo_cmd *cmd) |
51 | { |
52 | struct hal_reo_flush_cache *desc; |
53 | u8 avail_slot = ffz(hal->avail_blk_resource); |
54 | |
55 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { |
56 | if (avail_slot >= HAL_MAX_AVAIL_BLK_RES) |
57 | return -ENOSPC; |
58 | |
59 | hal->current_blk_index = avail_slot; |
60 | } |
61 | |
62 | tlv->tl = u32_encode_bits(v: HAL_REO_FLUSH_CACHE, HAL_TLV_HDR_TAG) | |
63 | u32_encode_bits(v: sizeof(*desc), HAL_TLV_HDR_LEN); |
64 | |
65 | desc = (struct hal_reo_flush_cache *)tlv->value; |
66 | memset_startat(desc, 0, cache_addr_lo); |
67 | |
68 | desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); |
69 | if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) |
70 | desc->cmd.info0 |= cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); |
71 | |
72 | desc->cache_addr_lo = cpu_to_le32(cmd->addr_lo); |
73 | desc->info0 = le32_encode_bits(v: cmd->addr_hi, |
74 | HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI); |
75 | |
76 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS) |
77 | desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS); |
78 | |
79 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { |
80 | desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE); |
81 | desc->info0 |= |
82 | le32_encode_bits(v: avail_slot, |
83 | HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX); |
84 | } |
85 | |
86 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL) |
87 | desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE); |
88 | |
89 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL) |
90 | desc->info0 |= cpu_to_le32(HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL); |
91 | |
92 | return le32_get_bits(v: desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); |
93 | } |
94 | |
95 | static int ath12k_hal_reo_cmd_update_rx_queue(struct hal_tlv_64_hdr *tlv, |
96 | struct ath12k_hal_reo_cmd *cmd) |
97 | { |
98 | struct hal_reo_update_rx_queue *desc; |
99 | |
100 | tlv->tl = u32_encode_bits(v: HAL_REO_UPDATE_RX_REO_QUEUE, HAL_TLV_HDR_TAG) | |
101 | u32_encode_bits(v: sizeof(*desc), HAL_TLV_HDR_LEN); |
102 | |
103 | desc = (struct hal_reo_update_rx_queue *)tlv->value; |
104 | memset_startat(desc, 0, queue_addr_lo); |
105 | |
106 | desc->cmd.info0 &= ~cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); |
107 | if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) |
108 | desc->cmd.info0 |= cpu_to_le32(HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED); |
109 | |
110 | desc->queue_addr_lo = cpu_to_le32(cmd->addr_lo); |
111 | desc->info0 = |
112 | le32_encode_bits(v: cmd->addr_hi, |
113 | HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI) | |
114 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM), |
115 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM) | |
116 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD), |
117 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD) | |
118 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC), |
119 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT) | |
120 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION), |
121 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION) | |
122 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN), |
123 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN) | |
124 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_AC), |
125 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC) | |
126 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR), |
127 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR) | |
128 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY), |
129 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY) | |
130 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE), |
131 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE) | |
132 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE), |
133 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE) | |
134 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE), |
135 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE) | |
136 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK), |
137 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK) | |
138 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN), |
139 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN) | |
140 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN), |
141 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN) | |
142 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE), |
143 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE) | |
144 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE), |
145 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE) | |
146 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG), |
147 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG) | |
148 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD), |
149 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD) | |
150 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN), |
151 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN) | |
152 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR), |
153 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR) | |
154 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID), |
155 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID) | |
156 | le32_encode_bits(v: !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN), |
157 | HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN); |
158 | |
159 | desc->info1 = |
160 | le32_encode_bits(v: cmd->rx_queue_num, |
161 | HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER) | |
162 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD), |
163 | HAL_REO_UPD_RX_QUEUE_INFO1_VLD) | |
164 | le32_encode_bits(v: u32_get_bits(v: cmd->upd1, HAL_REO_CMD_UPD1_ALDC), |
165 | HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER) | |
166 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION), |
167 | HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION) | |
168 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN), |
169 | HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN) | |
170 | le32_encode_bits(v: u32_get_bits(v: cmd->upd1, HAL_REO_CMD_UPD1_AC), |
171 | HAL_REO_UPD_RX_QUEUE_INFO1_AC) | |
172 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR), |
173 | HAL_REO_UPD_RX_QUEUE_INFO1_BAR) | |
174 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE), |
175 | HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE) | |
176 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY), |
177 | HAL_REO_UPD_RX_QUEUE_INFO1_RETRY) | |
178 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE), |
179 | HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE) | |
180 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK), |
181 | HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK) | |
182 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN), |
183 | HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN) | |
184 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN), |
185 | HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN) | |
186 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE), |
187 | HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE) | |
188 | le32_encode_bits(v: !!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG), |
189 | HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG); |
190 | |
191 | if (cmd->pn_size == 24) |
192 | cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24; |
193 | else if (cmd->pn_size == 48) |
194 | cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48; |
195 | else if (cmd->pn_size == 128) |
196 | cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128; |
197 | |
198 | if (cmd->ba_window_size < 1) |
199 | cmd->ba_window_size = 1; |
200 | |
201 | if (cmd->ba_window_size == 1) |
202 | cmd->ba_window_size++; |
203 | |
204 | desc->info2 = |
205 | le32_encode_bits(v: cmd->ba_window_size - 1, |
206 | HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE) | |
207 | le32_encode_bits(v: cmd->pn_size, HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE) | |
208 | le32_encode_bits(v: !!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD), |
209 | HAL_REO_UPD_RX_QUEUE_INFO2_SVLD) | |
210 | le32_encode_bits(v: u32_get_bits(v: cmd->upd2, HAL_REO_CMD_UPD2_SSN), |
211 | HAL_REO_UPD_RX_QUEUE_INFO2_SSN) | |
212 | le32_encode_bits(v: !!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR), |
213 | HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR) | |
214 | le32_encode_bits(v: !!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR), |
215 | HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR); |
216 | |
217 | return le32_get_bits(v: desc->cmd.info0, HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); |
218 | } |
219 | |
220 | int ath12k_hal_reo_cmd_send(struct ath12k_base *ab, struct hal_srng *srng, |
221 | enum hal_reo_cmd_type type, |
222 | struct ath12k_hal_reo_cmd *cmd) |
223 | { |
224 | struct hal_tlv_64_hdr *reo_desc; |
225 | int ret; |
226 | |
227 | spin_lock_bh(lock: &srng->lock); |
228 | |
229 | ath12k_hal_srng_access_begin(ab, srng); |
230 | reo_desc = ath12k_hal_srng_src_get_next_entry(ab, srng); |
231 | if (!reo_desc) { |
232 | ret = -ENOBUFS; |
233 | goto out; |
234 | } |
235 | |
236 | switch (type) { |
237 | case HAL_REO_CMD_GET_QUEUE_STATS: |
238 | ret = ath12k_hal_reo_cmd_queue_stats(tlv: reo_desc, cmd); |
239 | break; |
240 | case HAL_REO_CMD_FLUSH_CACHE: |
241 | ret = ath12k_hal_reo_cmd_flush_cache(hal: &ab->hal, tlv: reo_desc, cmd); |
242 | break; |
243 | case HAL_REO_CMD_UPDATE_RX_QUEUE: |
244 | ret = ath12k_hal_reo_cmd_update_rx_queue(tlv: reo_desc, cmd); |
245 | break; |
246 | case HAL_REO_CMD_FLUSH_QUEUE: |
247 | case HAL_REO_CMD_UNBLOCK_CACHE: |
248 | case HAL_REO_CMD_FLUSH_TIMEOUT_LIST: |
249 | ath12k_warn(ab, fmt: "Unsupported reo command %d\n" , type); |
250 | ret = -EOPNOTSUPP; |
251 | break; |
252 | default: |
253 | ath12k_warn(ab, fmt: "Unknown reo command %d\n" , type); |
254 | ret = -EINVAL; |
255 | break; |
256 | } |
257 | |
258 | out: |
259 | ath12k_hal_srng_access_end(ab, srng); |
260 | spin_unlock_bh(lock: &srng->lock); |
261 | |
262 | return ret; |
263 | } |
264 | |
265 | void ath12k_hal_rx_buf_addr_info_set(struct ath12k_buffer_addr *binfo, |
266 | dma_addr_t paddr, u32 cookie, u8 manager) |
267 | { |
268 | u32 paddr_lo, paddr_hi; |
269 | |
270 | paddr_lo = lower_32_bits(paddr); |
271 | paddr_hi = upper_32_bits(paddr); |
272 | binfo->info0 = le32_encode_bits(v: paddr_lo, BUFFER_ADDR_INFO0_ADDR); |
273 | binfo->info1 = le32_encode_bits(v: paddr_hi, BUFFER_ADDR_INFO1_ADDR) | |
274 | le32_encode_bits(v: cookie, BUFFER_ADDR_INFO1_SW_COOKIE) | |
275 | le32_encode_bits(v: manager, BUFFER_ADDR_INFO1_RET_BUF_MGR); |
276 | } |
277 | |
278 | void ath12k_hal_rx_buf_addr_info_get(struct ath12k_buffer_addr *binfo, |
279 | dma_addr_t *paddr, |
280 | u32 *cookie, u8 *rbm) |
281 | { |
282 | *paddr = (((u64)le32_get_bits(v: binfo->info1, BUFFER_ADDR_INFO1_ADDR)) << 32) | |
283 | le32_get_bits(v: binfo->info0, BUFFER_ADDR_INFO0_ADDR); |
284 | *cookie = le32_get_bits(v: binfo->info1, BUFFER_ADDR_INFO1_SW_COOKIE); |
285 | *rbm = le32_get_bits(v: binfo->info1, BUFFER_ADDR_INFO1_RET_BUF_MGR); |
286 | } |
287 | |
288 | void ath12k_hal_rx_msdu_link_info_get(struct hal_rx_msdu_link *link, u32 *num_msdus, |
289 | u32 *msdu_cookies, |
290 | enum hal_rx_buf_return_buf_manager *rbm) |
291 | { |
292 | struct hal_rx_msdu_details *msdu; |
293 | u32 val; |
294 | int i; |
295 | |
296 | *num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC; |
297 | |
298 | msdu = &link->msdu_link[0]; |
299 | *rbm = le32_get_bits(v: msdu->buf_addr_info.info1, |
300 | BUFFER_ADDR_INFO1_RET_BUF_MGR); |
301 | |
302 | for (i = 0; i < *num_msdus; i++) { |
303 | msdu = &link->msdu_link[i]; |
304 | |
305 | val = le32_get_bits(v: msdu->buf_addr_info.info0, |
306 | BUFFER_ADDR_INFO0_ADDR); |
307 | if (val == 0) { |
308 | *num_msdus = i; |
309 | break; |
310 | } |
311 | *msdu_cookies = le32_get_bits(v: msdu->buf_addr_info.info1, |
312 | BUFFER_ADDR_INFO1_SW_COOKIE); |
313 | msdu_cookies++; |
314 | } |
315 | } |
316 | |
317 | int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, |
318 | struct hal_reo_dest_ring *desc, |
319 | dma_addr_t *paddr, u32 *desc_bank) |
320 | { |
321 | enum hal_reo_dest_ring_push_reason push_reason; |
322 | enum hal_reo_dest_ring_error_code err_code; |
323 | u32 cookie, val; |
324 | |
325 | push_reason = le32_get_bits(v: desc->info0, |
326 | HAL_REO_DEST_RING_INFO0_PUSH_REASON); |
327 | err_code = le32_get_bits(v: desc->info0, |
328 | HAL_REO_DEST_RING_INFO0_ERROR_CODE); |
329 | ab->soc_stats.reo_error[err_code]++; |
330 | |
331 | if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED && |
332 | push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { |
333 | ath12k_warn(ab, fmt: "expected error push reason code, received %d\n" , |
334 | push_reason); |
335 | return -EINVAL; |
336 | } |
337 | |
338 | val = le32_get_bits(v: desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); |
339 | if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { |
340 | ath12k_warn(ab, fmt: "expected buffer type link_desc" ); |
341 | return -EINVAL; |
342 | } |
343 | |
344 | ath12k_hal_rx_reo_ent_paddr_get(ab, buff_addr: &desc->buf_addr_info, paddr, cookie: &cookie); |
345 | *desc_bank = u32_get_bits(v: cookie, DP_LINK_DESC_BANK_MASK); |
346 | |
347 | return 0; |
348 | } |
349 | |
350 | int ath12k_hal_wbm_desc_parse_err(struct ath12k_base *ab, void *desc, |
351 | struct hal_rx_wbm_rel_info *rel_info) |
352 | { |
353 | struct hal_wbm_release_ring *wbm_desc = desc; |
354 | struct hal_wbm_release_ring_cc_rx *wbm_cc_desc = desc; |
355 | enum hal_wbm_rel_desc_type type; |
356 | enum hal_wbm_rel_src_module rel_src; |
357 | bool hw_cc_done; |
358 | u64 desc_va; |
359 | u32 val; |
360 | |
361 | type = le32_get_bits(v: wbm_desc->info0, HAL_WBM_RELEASE_INFO0_DESC_TYPE); |
362 | /* We expect only WBM_REL buffer type */ |
363 | if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) { |
364 | WARN_ON(1); |
365 | return -EINVAL; |
366 | } |
367 | |
368 | rel_src = le32_get_bits(v: wbm_desc->info0, |
369 | HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE); |
370 | if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA && |
371 | rel_src != HAL_WBM_REL_SRC_MODULE_REO) |
372 | return -EINVAL; |
373 | |
374 | /* The format of wbm rel ring desc changes based on the |
375 | * hw cookie conversion status |
376 | */ |
377 | hw_cc_done = le32_get_bits(v: wbm_desc->info0, |
378 | HAL_WBM_RELEASE_RX_INFO0_CC_STATUS); |
379 | |
380 | if (!hw_cc_done) { |
381 | val = le32_get_bits(v: wbm_desc->buf_addr_info.info1, |
382 | BUFFER_ADDR_INFO1_RET_BUF_MGR); |
383 | if (val != HAL_RX_BUF_RBM_SW3_BM) { |
384 | ab->soc_stats.invalid_rbm++; |
385 | return -EINVAL; |
386 | } |
387 | |
388 | rel_info->cookie = le32_get_bits(v: wbm_desc->buf_addr_info.info1, |
389 | BUFFER_ADDR_INFO1_SW_COOKIE); |
390 | |
391 | rel_info->rx_desc = NULL; |
392 | } else { |
393 | val = le32_get_bits(v: wbm_cc_desc->info0, |
394 | HAL_WBM_RELEASE_RX_CC_INFO0_RBM); |
395 | if (val != HAL_RX_BUF_RBM_SW3_BM) { |
396 | ab->soc_stats.invalid_rbm++; |
397 | return -EINVAL; |
398 | } |
399 | |
400 | rel_info->cookie = le32_get_bits(v: wbm_cc_desc->info1, |
401 | HAL_WBM_RELEASE_RX_CC_INFO1_COOKIE); |
402 | |
403 | desc_va = ((u64)le32_to_cpu(wbm_cc_desc->buf_va_hi) << 32 | |
404 | le32_to_cpu(wbm_cc_desc->buf_va_lo)); |
405 | rel_info->rx_desc = |
406 | (struct ath12k_rx_desc_info *)((unsigned long)desc_va); |
407 | } |
408 | |
409 | rel_info->err_rel_src = rel_src; |
410 | rel_info->hw_cc_done = hw_cc_done; |
411 | |
412 | rel_info->first_msdu = le32_get_bits(v: wbm_desc->info3, |
413 | HAL_WBM_RELEASE_INFO3_FIRST_MSDU); |
414 | rel_info->last_msdu = le32_get_bits(v: wbm_desc->info3, |
415 | HAL_WBM_RELEASE_INFO3_LAST_MSDU); |
416 | rel_info->continuation = le32_get_bits(v: wbm_desc->info3, |
417 | HAL_WBM_RELEASE_INFO3_CONTINUATION); |
418 | |
419 | if (rel_info->err_rel_src == HAL_WBM_REL_SRC_MODULE_REO) { |
420 | rel_info->push_reason = |
421 | le32_get_bits(v: wbm_desc->info0, |
422 | HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON); |
423 | rel_info->err_code = |
424 | le32_get_bits(v: wbm_desc->info0, |
425 | HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE); |
426 | } else { |
427 | rel_info->push_reason = |
428 | le32_get_bits(v: wbm_desc->info0, |
429 | HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON); |
430 | rel_info->err_code = |
431 | le32_get_bits(v: wbm_desc->info0, |
432 | HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE); |
433 | } |
434 | |
435 | return 0; |
436 | } |
437 | |
438 | void ath12k_hal_rx_reo_ent_paddr_get(struct ath12k_base *ab, |
439 | struct ath12k_buffer_addr *buff_addr, |
440 | dma_addr_t *paddr, u32 *cookie) |
441 | { |
442 | *paddr = ((u64)(le32_get_bits(v: buff_addr->info1, |
443 | BUFFER_ADDR_INFO1_ADDR)) << 32) | |
444 | le32_get_bits(v: buff_addr->info0, BUFFER_ADDR_INFO0_ADDR); |
445 | |
446 | *cookie = le32_get_bits(v: buff_addr->info1, BUFFER_ADDR_INFO1_SW_COOKIE); |
447 | } |
448 | |
449 | void ath12k_hal_rx_msdu_link_desc_set(struct ath12k_base *ab, |
450 | struct hal_wbm_release_ring *dst_desc, |
451 | struct hal_wbm_release_ring *src_desc, |
452 | enum hal_wbm_rel_bm_act action) |
453 | { |
454 | dst_desc->buf_addr_info = src_desc->buf_addr_info; |
455 | dst_desc->info0 |= le32_encode_bits(v: HAL_WBM_REL_SRC_MODULE_SW, |
456 | HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE) | |
457 | le32_encode_bits(v: action, HAL_WBM_RELEASE_INFO0_BM_ACTION) | |
458 | le32_encode_bits(v: HAL_WBM_REL_DESC_TYPE_MSDU_LINK, |
459 | HAL_WBM_RELEASE_INFO0_DESC_TYPE); |
460 | } |
461 | |
462 | void ath12k_hal_reo_status_queue_stats(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, |
463 | struct hal_reo_status *status) |
464 | { |
465 | struct hal_reo_get_queue_stats_status *desc = |
466 | (struct hal_reo_get_queue_stats_status *)tlv->value; |
467 | |
468 | status->uniform_hdr.cmd_num = |
469 | le32_get_bits(v: desc->hdr.info0, |
470 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
471 | status->uniform_hdr.cmd_status = |
472 | le32_get_bits(v: desc->hdr.info0, |
473 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
474 | |
475 | ath12k_dbg(ab, ATH12K_DBG_HAL, "Queue stats status:\n" ); |
476 | ath12k_dbg(ab, ATH12K_DBG_HAL, "header: cmd_num %d status %d\n" , |
477 | status->uniform_hdr.cmd_num, |
478 | status->uniform_hdr.cmd_status); |
479 | ath12k_dbg(ab, ATH12K_DBG_HAL, "ssn %u cur_idx %u\n" , |
480 | le32_get_bits(desc->info0, |
481 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN), |
482 | le32_get_bits(desc->info0, |
483 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX)); |
484 | ath12k_dbg(ab, ATH12K_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n" , |
485 | desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]); |
486 | ath12k_dbg(ab, ATH12K_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n" , |
487 | desc->last_rx_enqueue_timestamp, |
488 | desc->last_rx_dequeue_timestamp); |
489 | ath12k_dbg(ab, ATH12K_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n" , |
490 | desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2], |
491 | desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5], |
492 | desc->rx_bitmap[6], desc->rx_bitmap[7]); |
493 | ath12k_dbg(ab, ATH12K_DBG_HAL, "count: cur_mpdu %u cur_msdu %u\n" , |
494 | le32_get_bits(desc->info1, |
495 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT), |
496 | le32_get_bits(desc->info1, |
497 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT)); |
498 | ath12k_dbg(ab, ATH12K_DBG_HAL, "fwd_timeout %u fwd_bar %u dup_count %u\n" , |
499 | le32_get_bits(desc->info2, |
500 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT), |
501 | le32_get_bits(desc->info2, |
502 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT), |
503 | le32_get_bits(desc->info2, |
504 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT)); |
505 | ath12k_dbg(ab, ATH12K_DBG_HAL, "frames_in_order %u bar_rcvd %u\n" , |
506 | le32_get_bits(desc->info3, |
507 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT), |
508 | le32_get_bits(desc->info3, |
509 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT)); |
510 | ath12k_dbg(ab, ATH12K_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n" , |
511 | desc->num_mpdu_frames, desc->num_msdu_frames, |
512 | desc->total_bytes); |
513 | ath12k_dbg(ab, ATH12K_DBG_HAL, "late_rcvd %u win_jump_2k %u hole_cnt %u\n" , |
514 | le32_get_bits(desc->info4, |
515 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU), |
516 | le32_get_bits(desc->info2, |
517 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_WINDOW_JMP2K), |
518 | le32_get_bits(desc->info4, |
519 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT)); |
520 | ath12k_dbg(ab, ATH12K_DBG_HAL, "looping count %u\n" , |
521 | le32_get_bits(desc->info5, |
522 | HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT)); |
523 | } |
524 | |
525 | void ath12k_hal_reo_flush_queue_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, |
526 | struct hal_reo_status *status) |
527 | { |
528 | struct hal_reo_flush_queue_status *desc = |
529 | (struct hal_reo_flush_queue_status *)tlv->value; |
530 | |
531 | status->uniform_hdr.cmd_num = |
532 | le32_get_bits(v: desc->hdr.info0, |
533 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
534 | status->uniform_hdr.cmd_status = |
535 | le32_get_bits(v: desc->hdr.info0, |
536 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
537 | status->u.flush_queue.err_detected = |
538 | le32_get_bits(v: desc->info0, |
539 | HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED); |
540 | } |
541 | |
542 | void ath12k_hal_reo_flush_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, |
543 | struct hal_reo_status *status) |
544 | { |
545 | struct ath12k_hal *hal = &ab->hal; |
546 | struct hal_reo_flush_cache_status *desc = |
547 | (struct hal_reo_flush_cache_status *)tlv->value; |
548 | |
549 | status->uniform_hdr.cmd_num = |
550 | le32_get_bits(v: desc->hdr.info0, |
551 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
552 | status->uniform_hdr.cmd_status = |
553 | le32_get_bits(v: desc->hdr.info0, |
554 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
555 | |
556 | status->u.flush_cache.err_detected = |
557 | le32_get_bits(v: desc->info0, |
558 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR); |
559 | status->u.flush_cache.err_code = |
560 | le32_get_bits(v: desc->info0, |
561 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE); |
562 | if (!status->u.flush_cache.err_code) |
563 | hal->avail_blk_resource |= BIT(hal->current_blk_index); |
564 | |
565 | status->u.flush_cache.cache_controller_flush_status_hit = |
566 | le32_get_bits(v: desc->info0, |
567 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT); |
568 | |
569 | status->u.flush_cache.cache_controller_flush_status_desc_type = |
570 | le32_get_bits(v: desc->info0, |
571 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE); |
572 | status->u.flush_cache.cache_controller_flush_status_client_id = |
573 | le32_get_bits(v: desc->info0, |
574 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID); |
575 | status->u.flush_cache.cache_controller_flush_status_err = |
576 | le32_get_bits(v: desc->info0, |
577 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR); |
578 | status->u.flush_cache.cache_controller_flush_status_cnt = |
579 | le32_get_bits(v: desc->info0, |
580 | HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT); |
581 | } |
582 | |
583 | void ath12k_hal_reo_unblk_cache_status(struct ath12k_base *ab, struct hal_tlv_64_hdr *tlv, |
584 | struct hal_reo_status *status) |
585 | { |
586 | struct ath12k_hal *hal = &ab->hal; |
587 | struct hal_reo_unblock_cache_status *desc = |
588 | (struct hal_reo_unblock_cache_status *)tlv->value; |
589 | |
590 | status->uniform_hdr.cmd_num = |
591 | le32_get_bits(v: desc->hdr.info0, |
592 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
593 | status->uniform_hdr.cmd_status = |
594 | le32_get_bits(v: desc->hdr.info0, |
595 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
596 | |
597 | status->u.unblock_cache.err_detected = |
598 | le32_get_bits(v: desc->info0, |
599 | HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR); |
600 | status->u.unblock_cache.unblock_type = |
601 | le32_get_bits(v: desc->info0, |
602 | HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE); |
603 | |
604 | if (!status->u.unblock_cache.err_detected && |
605 | status->u.unblock_cache.unblock_type == |
606 | HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE) |
607 | hal->avail_blk_resource &= ~BIT(hal->current_blk_index); |
608 | } |
609 | |
610 | void ath12k_hal_reo_flush_timeout_list_status(struct ath12k_base *ab, |
611 | struct hal_tlv_64_hdr *tlv, |
612 | struct hal_reo_status *status) |
613 | { |
614 | struct hal_reo_flush_timeout_list_status *desc = |
615 | (struct hal_reo_flush_timeout_list_status *)tlv->value; |
616 | |
617 | status->uniform_hdr.cmd_num = |
618 | le32_get_bits(v: desc->hdr.info0, |
619 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
620 | status->uniform_hdr.cmd_status = |
621 | le32_get_bits(v: desc->hdr.info0, |
622 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
623 | |
624 | status->u.timeout_list.err_detected = |
625 | le32_get_bits(v: desc->info0, |
626 | HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR); |
627 | status->u.timeout_list.list_empty = |
628 | le32_get_bits(v: desc->info0, |
629 | HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY); |
630 | |
631 | status->u.timeout_list.release_desc_cnt = |
632 | le32_get_bits(v: desc->info1, |
633 | HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT); |
634 | status->u.timeout_list.fwd_buf_cnt = |
635 | le32_get_bits(v: desc->info0, |
636 | HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT); |
637 | } |
638 | |
639 | void ath12k_hal_reo_desc_thresh_reached_status(struct ath12k_base *ab, |
640 | struct hal_tlv_64_hdr *tlv, |
641 | struct hal_reo_status *status) |
642 | { |
643 | struct hal_reo_desc_thresh_reached_status *desc = |
644 | (struct hal_reo_desc_thresh_reached_status *)tlv->value; |
645 | |
646 | status->uniform_hdr.cmd_num = |
647 | le32_get_bits(v: desc->hdr.info0, |
648 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
649 | status->uniform_hdr.cmd_status = |
650 | le32_get_bits(v: desc->hdr.info0, |
651 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
652 | |
653 | status->u.desc_thresh_reached.threshold_idx = |
654 | le32_get_bits(v: desc->info0, |
655 | HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX); |
656 | |
657 | status->u.desc_thresh_reached.link_desc_counter0 = |
658 | le32_get_bits(v: desc->info1, |
659 | HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0); |
660 | |
661 | status->u.desc_thresh_reached.link_desc_counter1 = |
662 | le32_get_bits(v: desc->info2, |
663 | HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1); |
664 | |
665 | status->u.desc_thresh_reached.link_desc_counter2 = |
666 | le32_get_bits(v: desc->info3, |
667 | HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2); |
668 | |
669 | status->u.desc_thresh_reached.link_desc_counter_sum = |
670 | le32_get_bits(v: desc->info4, |
671 | HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM); |
672 | } |
673 | |
674 | void ath12k_hal_reo_update_rx_reo_queue_status(struct ath12k_base *ab, |
675 | struct hal_tlv_64_hdr *tlv, |
676 | struct hal_reo_status *status) |
677 | { |
678 | struct hal_reo_status_hdr *desc = |
679 | (struct hal_reo_status_hdr *)tlv->value; |
680 | |
681 | status->uniform_hdr.cmd_num = |
682 | le32_get_bits(v: desc->info0, |
683 | HAL_REO_STATUS_HDR_INFO0_STATUS_NUM); |
684 | status->uniform_hdr.cmd_status = |
685 | le32_get_bits(v: desc->info0, |
686 | HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS); |
687 | } |
688 | |
689 | u32 ath12k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) |
690 | { |
691 | u32 num_ext_desc, num_1k_desc = 0; |
692 | |
693 | if (ba_window_size <= 1) { |
694 | if (tid != HAL_DESC_REO_NON_QOS_TID) |
695 | num_ext_desc = 1; |
696 | else |
697 | num_ext_desc = 0; |
698 | |
699 | } else if (ba_window_size <= 105) { |
700 | num_ext_desc = 1; |
701 | } else if (ba_window_size <= 210) { |
702 | num_ext_desc = 2; |
703 | } else if (ba_window_size <= 256) { |
704 | num_ext_desc = 3; |
705 | } else { |
706 | num_ext_desc = 10; |
707 | num_1k_desc = 1; |
708 | } |
709 | |
710 | return sizeof(struct hal_rx_reo_queue) + |
711 | (num_ext_desc * sizeof(struct hal_rx_reo_queue_ext)) + |
712 | (num_1k_desc * sizeof(struct hal_rx_reo_queue_1k)); |
713 | } |
714 | |
715 | void ath12k_hal_reo_qdesc_setup(struct hal_rx_reo_queue *qdesc, |
716 | int tid, u32 ba_window_size, |
717 | u32 start_seq, enum hal_pn_type type) |
718 | { |
719 | struct hal_rx_reo_queue_ext *ext_desc; |
720 | |
721 | ath12k_hal_reo_set_desc_hdr(hdr: &qdesc->desc_hdr, HAL_DESC_REO_OWNED, |
722 | HAL_DESC_REO_QUEUE_DESC, |
723 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); |
724 | |
725 | qdesc->rx_queue_num = le32_encode_bits(v: tid, HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER); |
726 | |
727 | qdesc->info0 = |
728 | le32_encode_bits(v: 1, HAL_RX_REO_QUEUE_INFO0_VLD) | |
729 | le32_encode_bits(v: 1, HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER) | |
730 | le32_encode_bits(v: ath12k_tid_to_ac(tid), HAL_RX_REO_QUEUE_INFO0_AC); |
731 | |
732 | if (ba_window_size < 1) |
733 | ba_window_size = 1; |
734 | |
735 | if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID) |
736 | ba_window_size++; |
737 | |
738 | if (ba_window_size == 1) |
739 | qdesc->info0 |= le32_encode_bits(v: 1, HAL_RX_REO_QUEUE_INFO0_RETRY); |
740 | |
741 | qdesc->info0 |= le32_encode_bits(v: ba_window_size - 1, |
742 | HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE); |
743 | switch (type) { |
744 | case HAL_PN_TYPE_NONE: |
745 | case HAL_PN_TYPE_WAPI_EVEN: |
746 | case HAL_PN_TYPE_WAPI_UNEVEN: |
747 | break; |
748 | case HAL_PN_TYPE_WPA: |
749 | qdesc->info0 |= |
750 | le32_encode_bits(v: 1, HAL_RX_REO_QUEUE_INFO0_PN_CHECK) | |
751 | le32_encode_bits(v: HAL_RX_REO_QUEUE_PN_SIZE_48, |
752 | HAL_RX_REO_QUEUE_INFO0_PN_SIZE); |
753 | break; |
754 | } |
755 | |
756 | /* TODO: Set Ignore ampdu flags based on BA window size and/or |
757 | * AMPDU capabilities |
758 | */ |
759 | qdesc->info0 |= le32_encode_bits(v: 1, HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG); |
760 | |
761 | qdesc->info1 |= le32_encode_bits(v: 0, HAL_RX_REO_QUEUE_INFO1_SVLD); |
762 | |
763 | if (start_seq <= 0xfff) |
764 | qdesc->info1 = le32_encode_bits(v: start_seq, |
765 | HAL_RX_REO_QUEUE_INFO1_SSN); |
766 | |
767 | if (tid == HAL_DESC_REO_NON_QOS_TID) |
768 | return; |
769 | |
770 | ext_desc = qdesc->ext_desc; |
771 | |
772 | /* TODO: HW queue descriptors are currently allocated for max BA |
773 | * window size for all QOS TIDs so that same descriptor can be used |
774 | * later when ADDBA request is received. This should be changed to |
775 | * allocate HW queue descriptors based on BA window size being |
776 | * negotiated (0 for non BA cases), and reallocate when BA window |
777 | * size changes and also send WMI message to FW to change the REO |
778 | * queue descriptor in Rx peer entry as part of dp_rx_tid_update. |
779 | */ |
780 | memset(ext_desc, 0, 3 * sizeof(*ext_desc)); |
781 | ath12k_hal_reo_set_desc_hdr(hdr: &ext_desc->desc_hdr, HAL_DESC_REO_OWNED, |
782 | HAL_DESC_REO_QUEUE_EXT_DESC, |
783 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); |
784 | ext_desc++; |
785 | ath12k_hal_reo_set_desc_hdr(hdr: &ext_desc->desc_hdr, HAL_DESC_REO_OWNED, |
786 | HAL_DESC_REO_QUEUE_EXT_DESC, |
787 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); |
788 | ext_desc++; |
789 | ath12k_hal_reo_set_desc_hdr(hdr: &ext_desc->desc_hdr, HAL_DESC_REO_OWNED, |
790 | HAL_DESC_REO_QUEUE_EXT_DESC, |
791 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); |
792 | } |
793 | |
794 | void ath12k_hal_reo_init_cmd_ring(struct ath12k_base *ab, |
795 | struct hal_srng *srng) |
796 | { |
797 | struct hal_srng_params params; |
798 | struct hal_tlv_64_hdr *tlv; |
799 | struct hal_reo_get_queue_stats *desc; |
800 | int i, cmd_num = 1; |
801 | int entry_size; |
802 | u8 *entry; |
803 | |
804 | memset(¶ms, 0, sizeof(params)); |
805 | |
806 | entry_size = ath12k_hal_srng_get_entrysize(ab, ring_type: HAL_REO_CMD); |
807 | ath12k_hal_srng_get_params(ab, srng, params: ¶ms); |
808 | entry = (u8 *)params.ring_base_vaddr; |
809 | |
810 | for (i = 0; i < params.num_entries; i++) { |
811 | tlv = (struct hal_tlv_64_hdr *)entry; |
812 | desc = (struct hal_reo_get_queue_stats *)tlv->value; |
813 | desc->cmd.info0 = le32_encode_bits(v: cmd_num++, |
814 | HAL_REO_CMD_HDR_INFO0_CMD_NUMBER); |
815 | entry += entry_size; |
816 | } |
817 | } |
818 | |
819 | void ath12k_hal_reo_hw_setup(struct ath12k_base *ab, u32 ring_hash_map) |
820 | { |
821 | u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; |
822 | u32 val; |
823 | |
824 | val = ath12k_hif_read32(ab, address: reo_base + HAL_REO1_GEN_ENABLE); |
825 | |
826 | val |= u32_encode_bits(v: 1, HAL_REO1_GEN_ENABLE_AGING_LIST_ENABLE) | |
827 | u32_encode_bits(v: 1, HAL_REO1_GEN_ENABLE_AGING_FLUSH_ENABLE); |
828 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_GEN_ENABLE, data: val); |
829 | |
830 | val = ath12k_hif_read32(ab, address: reo_base + HAL_REO1_MISC_CTRL_ADDR(ab)); |
831 | |
832 | val &= ~(HAL_REO1_MISC_CTL_FRAG_DST_RING | |
833 | HAL_REO1_MISC_CTL_BAR_DST_RING); |
834 | val |= u32_encode_bits(v: HAL_SRNG_RING_ID_REO2SW0, |
835 | HAL_REO1_MISC_CTL_FRAG_DST_RING); |
836 | val |= u32_encode_bits(v: HAL_SRNG_RING_ID_REO2SW0, |
837 | HAL_REO1_MISC_CTL_BAR_DST_RING); |
838 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_MISC_CTRL_ADDR(ab), data: val); |
839 | |
840 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_AGING_THRESH_IX_0(ab), |
841 | HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); |
842 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_AGING_THRESH_IX_1(ab), |
843 | HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); |
844 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_AGING_THRESH_IX_2(ab), |
845 | HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC); |
846 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), |
847 | HAL_DEFAULT_VO_REO_TIMEOUT_USEC); |
848 | |
849 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, |
850 | data: ring_hash_map); |
851 | ath12k_hif_write32(ab, address: reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, |
852 | data: ring_hash_map); |
853 | } |
854 | |