1 | // SPDX-License-Identifier: BSD-3-Clause-Clear |
2 | /* |
3 | * Copyright (c) 2018-2019 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 ath11k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr, |
15 | u8 owner, u8 buffer_type, u32 magic) |
16 | { |
17 | hdr->info0 = FIELD_PREP(HAL_DESC_HDR_INFO0_OWNER, owner) | |
18 | FIELD_PREP(HAL_DESC_HDR_INFO0_BUF_TYPE, buffer_type); |
19 | |
20 | /* Magic pattern in reserved bits for debugging */ |
21 | hdr->info0 |= FIELD_PREP(HAL_DESC_HDR_INFO0_DBG_RESERVED, magic); |
22 | } |
23 | |
24 | static int ath11k_hal_reo_cmd_queue_stats(struct hal_tlv_hdr *tlv, |
25 | struct ath11k_hal_reo_cmd *cmd) |
26 | { |
27 | struct hal_reo_get_queue_stats *desc; |
28 | |
29 | tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_GET_QUEUE_STATS) | |
30 | FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); |
31 | |
32 | desc = (struct hal_reo_get_queue_stats *)tlv->value; |
33 | memset_startat(desc, 0, queue_addr_lo); |
34 | |
35 | desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; |
36 | if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) |
37 | desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; |
38 | |
39 | desc->queue_addr_lo = cmd->addr_lo; |
40 | desc->info0 = FIELD_PREP(HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI, |
41 | cmd->addr_hi); |
42 | if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR) |
43 | desc->info0 |= HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS; |
44 | |
45 | return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); |
46 | } |
47 | |
48 | static int ath11k_hal_reo_cmd_flush_cache(struct ath11k_hal *hal, struct hal_tlv_hdr *tlv, |
49 | struct ath11k_hal_reo_cmd *cmd) |
50 | { |
51 | struct hal_reo_flush_cache *desc; |
52 | u8 avail_slot = ffz(hal->avail_blk_resource); |
53 | |
54 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { |
55 | if (avail_slot >= HAL_MAX_AVAIL_BLK_RES) |
56 | return -ENOSPC; |
57 | |
58 | hal->current_blk_index = avail_slot; |
59 | } |
60 | |
61 | tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_FLUSH_CACHE) | |
62 | FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); |
63 | |
64 | desc = (struct hal_reo_flush_cache *)tlv->value; |
65 | memset_startat(desc, 0, cache_addr_lo); |
66 | |
67 | desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; |
68 | if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) |
69 | desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; |
70 | |
71 | desc->cache_addr_lo = cmd->addr_lo; |
72 | desc->info0 = FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI, |
73 | cmd->addr_hi); |
74 | |
75 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS) |
76 | desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS; |
77 | |
78 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) { |
79 | desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE; |
80 | desc->info0 |= |
81 | FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX, |
82 | avail_slot); |
83 | } |
84 | |
85 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL) |
86 | desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE; |
87 | |
88 | if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL) |
89 | desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL; |
90 | |
91 | return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); |
92 | } |
93 | |
94 | static int ath11k_hal_reo_cmd_update_rx_queue(struct hal_tlv_hdr *tlv, |
95 | struct ath11k_hal_reo_cmd *cmd) |
96 | { |
97 | struct hal_reo_update_rx_queue *desc; |
98 | |
99 | tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_UPDATE_RX_REO_QUEUE) | |
100 | FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc)); |
101 | |
102 | desc = (struct hal_reo_update_rx_queue *)tlv->value; |
103 | memset_startat(desc, 0, queue_addr_lo); |
104 | |
105 | desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; |
106 | if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS) |
107 | desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED; |
108 | |
109 | desc->queue_addr_lo = cmd->addr_lo; |
110 | desc->info0 = |
111 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI, |
112 | cmd->addr_hi) | |
113 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM, |
114 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM)) | |
115 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD, |
116 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD)) | |
117 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT, |
118 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC)) | |
119 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION, |
120 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION)) | |
121 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN, |
122 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN)) | |
123 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC, |
124 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_AC)) | |
125 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR, |
126 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR)) | |
127 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY, |
128 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY)) | |
129 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE, |
130 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE)) | |
131 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE, |
132 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE)) | |
133 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE, |
134 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE)) | |
135 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK, |
136 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK)) | |
137 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN, |
138 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN)) | |
139 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN, |
140 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN)) | |
141 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE, |
142 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE)) | |
143 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE, |
144 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE)) | |
145 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG, |
146 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG)) | |
147 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD, |
148 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD)) | |
149 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN, |
150 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN)) | |
151 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR, |
152 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR)) | |
153 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID, |
154 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID)) | |
155 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN, |
156 | !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN)); |
157 | |
158 | desc->info1 = |
159 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER, |
160 | cmd->rx_queue_num) | |
161 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_VLD, |
162 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD)) | |
163 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER, |
164 | FIELD_GET(HAL_REO_CMD_UPD1_ALDC, cmd->upd1)) | |
165 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION, |
166 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION)) | |
167 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN, |
168 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN)) | |
169 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_AC, |
170 | FIELD_GET(HAL_REO_CMD_UPD1_AC, cmd->upd1)) | |
171 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_BAR, |
172 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR)) | |
173 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE, |
174 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE)) | |
175 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RETRY, |
176 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY)) | |
177 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE, |
178 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE)) | |
179 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK, |
180 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK)) | |
181 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN, |
182 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN)) | |
183 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN, |
184 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN)) | |
185 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE, |
186 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE)) | |
187 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG, |
188 | !!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG)); |
189 | |
190 | if (cmd->pn_size == 24) |
191 | cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24; |
192 | else if (cmd->pn_size == 48) |
193 | cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48; |
194 | else if (cmd->pn_size == 128) |
195 | cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128; |
196 | |
197 | if (cmd->ba_window_size < 1) |
198 | cmd->ba_window_size = 1; |
199 | |
200 | if (cmd->ba_window_size == 1) |
201 | cmd->ba_window_size++; |
202 | |
203 | desc->info2 = |
204 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE, |
205 | cmd->ba_window_size - 1) | |
206 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE, cmd->pn_size) | |
207 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SVLD, |
208 | !!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD)) | |
209 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SSN, |
210 | FIELD_GET(HAL_REO_CMD_UPD2_SSN, cmd->upd2)) | |
211 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR, |
212 | !!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR)) | |
213 | FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR, |
214 | !!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR)); |
215 | |
216 | return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0); |
217 | } |
218 | |
219 | int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng, |
220 | enum hal_reo_cmd_type type, |
221 | struct ath11k_hal_reo_cmd *cmd) |
222 | { |
223 | struct hal_tlv_hdr *reo_desc; |
224 | int ret; |
225 | |
226 | spin_lock_bh(lock: &srng->lock); |
227 | |
228 | ath11k_hal_srng_access_begin(ab, srng); |
229 | reo_desc = (struct hal_tlv_hdr *)ath11k_hal_srng_src_get_next_entry(ab, srng); |
230 | if (!reo_desc) { |
231 | ret = -ENOBUFS; |
232 | goto out; |
233 | } |
234 | |
235 | switch (type) { |
236 | case HAL_REO_CMD_GET_QUEUE_STATS: |
237 | ret = ath11k_hal_reo_cmd_queue_stats(tlv: reo_desc, cmd); |
238 | break; |
239 | case HAL_REO_CMD_FLUSH_CACHE: |
240 | ret = ath11k_hal_reo_cmd_flush_cache(hal: &ab->hal, tlv: reo_desc, cmd); |
241 | break; |
242 | case HAL_REO_CMD_UPDATE_RX_QUEUE: |
243 | ret = ath11k_hal_reo_cmd_update_rx_queue(tlv: reo_desc, cmd); |
244 | break; |
245 | case HAL_REO_CMD_FLUSH_QUEUE: |
246 | case HAL_REO_CMD_UNBLOCK_CACHE: |
247 | case HAL_REO_CMD_FLUSH_TIMEOUT_LIST: |
248 | ath11k_warn(ab, fmt: "Unsupported reo command %d\n" , type); |
249 | ret = -EOPNOTSUPP; |
250 | break; |
251 | default: |
252 | ath11k_warn(ab, fmt: "Unknown reo command %d\n" , type); |
253 | ret = -EINVAL; |
254 | break; |
255 | } |
256 | |
257 | ath11k_dp_shadow_start_timer(ab, srng, update_timer: &ab->dp.reo_cmd_timer); |
258 | |
259 | out: |
260 | ath11k_hal_srng_access_end(ab, srng); |
261 | spin_unlock_bh(lock: &srng->lock); |
262 | |
263 | return ret; |
264 | } |
265 | |
266 | void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr, |
267 | u32 cookie, u8 manager) |
268 | { |
269 | struct ath11k_buffer_addr *binfo = desc; |
270 | u32 paddr_lo, paddr_hi; |
271 | |
272 | paddr_lo = lower_32_bits(paddr); |
273 | paddr_hi = upper_32_bits(paddr); |
274 | binfo->info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr_lo); |
275 | binfo->info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, paddr_hi) | |
276 | FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie) | |
277 | FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, manager); |
278 | } |
279 | |
280 | void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr, |
281 | u32 *cookie, u8 *rbm) |
282 | { |
283 | struct ath11k_buffer_addr *binfo = desc; |
284 | |
285 | *paddr = |
286 | (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) | |
287 | FIELD_GET(BUFFER_ADDR_INFO0_ADDR, binfo->info0); |
288 | *cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, binfo->info1); |
289 | *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, binfo->info1); |
290 | } |
291 | |
292 | void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus, |
293 | u32 *msdu_cookies, |
294 | enum hal_rx_buf_return_buf_manager *rbm) |
295 | { |
296 | struct hal_rx_msdu_link *link = link_desc; |
297 | struct hal_rx_msdu_details *msdu; |
298 | int i; |
299 | |
300 | *num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC; |
301 | |
302 | msdu = &link->msdu_link[0]; |
303 | *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, |
304 | msdu->buf_addr_info.info1); |
305 | |
306 | for (i = 0; i < *num_msdus; i++) { |
307 | msdu = &link->msdu_link[i]; |
308 | |
309 | if (!FIELD_GET(BUFFER_ADDR_INFO0_ADDR, |
310 | msdu->buf_addr_info.info0)) { |
311 | *num_msdus = i; |
312 | break; |
313 | } |
314 | *msdu_cookies = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, |
315 | msdu->buf_addr_info.info1); |
316 | msdu_cookies++; |
317 | } |
318 | } |
319 | |
320 | int ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc, |
321 | dma_addr_t *paddr, u32 *desc_bank) |
322 | { |
323 | struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc; |
324 | enum hal_reo_dest_ring_push_reason push_reason; |
325 | enum hal_reo_dest_ring_error_code err_code; |
326 | |
327 | push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON, |
328 | desc->info0); |
329 | err_code = FIELD_GET(HAL_REO_DEST_RING_INFO0_ERROR_CODE, |
330 | desc->info0); |
331 | ab->soc_stats.reo_error[err_code]++; |
332 | |
333 | if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED && |
334 | push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) { |
335 | ath11k_warn(ab, fmt: "expected error push reason code, received %d\n" , |
336 | push_reason); |
337 | return -EINVAL; |
338 | } |
339 | |
340 | if (FIELD_GET(HAL_REO_DEST_RING_INFO0_BUFFER_TYPE, desc->info0) != |
341 | HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { |
342 | ath11k_warn(ab, fmt: "expected buffer type link_desc" ); |
343 | return -EINVAL; |
344 | } |
345 | |
346 | ath11k_hal_rx_reo_ent_paddr_get(ab, desc: rx_desc, paddr, desc_bank); |
347 | |
348 | return 0; |
349 | } |
350 | |
351 | int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc, |
352 | struct hal_rx_wbm_rel_info *rel_info) |
353 | { |
354 | struct hal_wbm_release_ring *wbm_desc = desc; |
355 | enum hal_wbm_rel_desc_type type; |
356 | enum hal_wbm_rel_src_module rel_src; |
357 | enum hal_rx_buf_return_buf_manager ret_buf_mgr; |
358 | |
359 | type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE, |
360 | wbm_desc->info0); |
361 | /* We expect only WBM_REL buffer type */ |
362 | if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) { |
363 | WARN_ON(1); |
364 | return -EINVAL; |
365 | } |
366 | |
367 | rel_src = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, |
368 | wbm_desc->info0); |
369 | if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA && |
370 | rel_src != HAL_WBM_REL_SRC_MODULE_REO) |
371 | return -EINVAL; |
372 | |
373 | ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, |
374 | wbm_desc->buf_addr_info.info1); |
375 | if (ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) { |
376 | ab->soc_stats.invalid_rbm++; |
377 | return -EINVAL; |
378 | } |
379 | |
380 | rel_info->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, |
381 | wbm_desc->buf_addr_info.info1); |
382 | rel_info->err_rel_src = rel_src; |
383 | if (rel_src == HAL_WBM_REL_SRC_MODULE_REO) { |
384 | rel_info->push_reason = |
385 | FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON, |
386 | wbm_desc->info0); |
387 | rel_info->err_code = |
388 | FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE, |
389 | wbm_desc->info0); |
390 | } else { |
391 | rel_info->push_reason = |
392 | FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON, |
393 | wbm_desc->info0); |
394 | rel_info->err_code = |
395 | FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE, |
396 | wbm_desc->info0); |
397 | } |
398 | |
399 | rel_info->first_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_FIRST_MSDU, |
400 | wbm_desc->info2); |
401 | rel_info->last_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_LAST_MSDU, |
402 | wbm_desc->info2); |
403 | return 0; |
404 | } |
405 | |
406 | void ath11k_hal_rx_reo_ent_paddr_get(struct ath11k_base *ab, void *desc, |
407 | dma_addr_t *paddr, u32 *desc_bank) |
408 | { |
409 | struct ath11k_buffer_addr *buff_addr = desc; |
410 | |
411 | *paddr = ((u64)(FIELD_GET(BUFFER_ADDR_INFO1_ADDR, buff_addr->info1)) << 32) | |
412 | FIELD_GET(BUFFER_ADDR_INFO0_ADDR, buff_addr->info0); |
413 | |
414 | *desc_bank = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, buff_addr->info1); |
415 | } |
416 | |
417 | void ath11k_hal_rx_msdu_link_desc_set(struct ath11k_base *ab, void *desc, |
418 | void *link_desc, |
419 | enum hal_wbm_rel_bm_act action) |
420 | { |
421 | struct hal_wbm_release_ring *dst_desc = desc; |
422 | struct hal_wbm_release_ring *src_desc = link_desc; |
423 | |
424 | dst_desc->buf_addr_info = src_desc->buf_addr_info; |
425 | dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, |
426 | HAL_WBM_REL_SRC_MODULE_SW) | |
427 | FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) | |
428 | FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE, |
429 | HAL_WBM_REL_DESC_TYPE_MSDU_LINK); |
430 | } |
431 | |
432 | void ath11k_hal_reo_status_queue_stats(struct ath11k_base *ab, u32 *reo_desc, |
433 | struct hal_reo_status *status) |
434 | { |
435 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
436 | struct hal_reo_get_queue_stats_status *desc = |
437 | (struct hal_reo_get_queue_stats_status *)tlv->value; |
438 | |
439 | status->uniform_hdr.cmd_num = |
440 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
441 | desc->hdr.info0); |
442 | status->uniform_hdr.cmd_status = |
443 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
444 | desc->hdr.info0); |
445 | |
446 | ath11k_dbg(ab, ATH11K_DBG_HAL, "Queue stats status:\n" ); |
447 | ath11k_dbg(ab, ATH11K_DBG_HAL, "header: cmd_num %d status %d\n" , |
448 | status->uniform_hdr.cmd_num, |
449 | status->uniform_hdr.cmd_status); |
450 | ath11k_dbg(ab, ATH11K_DBG_HAL, "ssn %ld cur_idx %ld\n" , |
451 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN, |
452 | desc->info0), |
453 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX, |
454 | desc->info0)); |
455 | ath11k_dbg(ab, ATH11K_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n" , |
456 | desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]); |
457 | ath11k_dbg(ab, ATH11K_DBG_HAL, |
458 | "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n" , |
459 | desc->last_rx_enqueue_timestamp, |
460 | desc->last_rx_dequeue_timestamp); |
461 | ath11k_dbg(ab, ATH11K_DBG_HAL, |
462 | "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n" , |
463 | desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2], |
464 | desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5], |
465 | desc->rx_bitmap[6], desc->rx_bitmap[7]); |
466 | ath11k_dbg(ab, ATH11K_DBG_HAL, "count: cur_mpdu %ld cur_msdu %ld\n" , |
467 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT, |
468 | desc->info1), |
469 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT, |
470 | desc->info1)); |
471 | ath11k_dbg(ab, ATH11K_DBG_HAL, "fwd_timeout %ld fwd_bar %ld dup_count %ld\n" , |
472 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT, |
473 | desc->info2), |
474 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT, |
475 | desc->info2), |
476 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT, |
477 | desc->info2)); |
478 | ath11k_dbg(ab, ATH11K_DBG_HAL, "frames_in_order %ld bar_rcvd %ld\n" , |
479 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT, |
480 | desc->info3), |
481 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT, |
482 | desc->info3)); |
483 | ath11k_dbg(ab, ATH11K_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n" , |
484 | desc->num_mpdu_frames, desc->num_msdu_frames, |
485 | desc->total_bytes); |
486 | ath11k_dbg(ab, ATH11K_DBG_HAL, "late_rcvd %ld win_jump_2k %ld hole_cnt %ld\n" , |
487 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU, |
488 | desc->info4), |
489 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_WINDOW_JMP2K, |
490 | desc->info4), |
491 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT, |
492 | desc->info4)); |
493 | ath11k_dbg(ab, ATH11K_DBG_HAL, "looping count %ld\n" , |
494 | FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT, |
495 | desc->info5)); |
496 | } |
497 | |
498 | int ath11k_hal_reo_process_status(u8 *reo_desc, u8 *status) |
499 | { |
500 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
501 | struct hal_reo_status_hdr *hdr; |
502 | |
503 | hdr = (struct hal_reo_status_hdr *)tlv->value; |
504 | *status = FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, hdr->info0); |
505 | |
506 | return FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, hdr->info0); |
507 | } |
508 | |
509 | void ath11k_hal_reo_flush_queue_status(struct ath11k_base *ab, u32 *reo_desc, |
510 | struct hal_reo_status *status) |
511 | { |
512 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
513 | struct hal_reo_flush_queue_status *desc = |
514 | (struct hal_reo_flush_queue_status *)tlv->value; |
515 | |
516 | status->uniform_hdr.cmd_num = |
517 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
518 | desc->hdr.info0); |
519 | status->uniform_hdr.cmd_status = |
520 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
521 | desc->hdr.info0); |
522 | status->u.flush_queue.err_detected = |
523 | FIELD_GET(HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED, |
524 | desc->info0); |
525 | } |
526 | |
527 | void ath11k_hal_reo_flush_cache_status(struct ath11k_base *ab, u32 *reo_desc, |
528 | struct hal_reo_status *status) |
529 | { |
530 | struct ath11k_hal *hal = &ab->hal; |
531 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
532 | struct hal_reo_flush_cache_status *desc = |
533 | (struct hal_reo_flush_cache_status *)tlv->value; |
534 | |
535 | status->uniform_hdr.cmd_num = |
536 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
537 | desc->hdr.info0); |
538 | status->uniform_hdr.cmd_status = |
539 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
540 | desc->hdr.info0); |
541 | |
542 | status->u.flush_cache.err_detected = |
543 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR, |
544 | desc->info0); |
545 | status->u.flush_cache.err_code = |
546 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE, |
547 | desc->info0); |
548 | if (!status->u.flush_cache.err_code) |
549 | hal->avail_blk_resource |= BIT(hal->current_blk_index); |
550 | |
551 | status->u.flush_cache.cache_controller_flush_status_hit = |
552 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT, |
553 | desc->info0); |
554 | |
555 | status->u.flush_cache.cache_controller_flush_status_desc_type = |
556 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE, |
557 | desc->info0); |
558 | status->u.flush_cache.cache_controller_flush_status_client_id = |
559 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID, |
560 | desc->info0); |
561 | status->u.flush_cache.cache_controller_flush_status_err = |
562 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR, |
563 | desc->info0); |
564 | status->u.flush_cache.cache_controller_flush_status_cnt = |
565 | FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT, |
566 | desc->info0); |
567 | } |
568 | |
569 | void ath11k_hal_reo_unblk_cache_status(struct ath11k_base *ab, u32 *reo_desc, |
570 | struct hal_reo_status *status) |
571 | { |
572 | struct ath11k_hal *hal = &ab->hal; |
573 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
574 | struct hal_reo_unblock_cache_status *desc = |
575 | (struct hal_reo_unblock_cache_status *)tlv->value; |
576 | |
577 | status->uniform_hdr.cmd_num = |
578 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
579 | desc->hdr.info0); |
580 | status->uniform_hdr.cmd_status = |
581 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
582 | desc->hdr.info0); |
583 | |
584 | status->u.unblock_cache.err_detected = |
585 | FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR, |
586 | desc->info0); |
587 | status->u.unblock_cache.unblock_type = |
588 | FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE, |
589 | desc->info0); |
590 | |
591 | if (!status->u.unblock_cache.err_detected && |
592 | status->u.unblock_cache.unblock_type == |
593 | HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE) |
594 | hal->avail_blk_resource &= ~BIT(hal->current_blk_index); |
595 | } |
596 | |
597 | void ath11k_hal_reo_flush_timeout_list_status(struct ath11k_base *ab, |
598 | u32 *reo_desc, |
599 | struct hal_reo_status *status) |
600 | { |
601 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
602 | struct hal_reo_flush_timeout_list_status *desc = |
603 | (struct hal_reo_flush_timeout_list_status *)tlv->value; |
604 | |
605 | status->uniform_hdr.cmd_num = |
606 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
607 | desc->hdr.info0); |
608 | status->uniform_hdr.cmd_status = |
609 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
610 | desc->hdr.info0); |
611 | |
612 | status->u.timeout_list.err_detected = |
613 | FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR, |
614 | desc->info0); |
615 | status->u.timeout_list.list_empty = |
616 | FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY, |
617 | desc->info0); |
618 | |
619 | status->u.timeout_list.release_desc_cnt = |
620 | FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT, |
621 | desc->info1); |
622 | status->u.timeout_list.fwd_buf_cnt = |
623 | FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT, |
624 | desc->info1); |
625 | } |
626 | |
627 | void ath11k_hal_reo_desc_thresh_reached_status(struct ath11k_base *ab, |
628 | u32 *reo_desc, |
629 | struct hal_reo_status *status) |
630 | { |
631 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
632 | struct hal_reo_desc_thresh_reached_status *desc = |
633 | (struct hal_reo_desc_thresh_reached_status *)tlv->value; |
634 | |
635 | status->uniform_hdr.cmd_num = |
636 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
637 | desc->hdr.info0); |
638 | status->uniform_hdr.cmd_status = |
639 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
640 | desc->hdr.info0); |
641 | |
642 | status->u.desc_thresh_reached.threshold_idx = |
643 | FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX, |
644 | desc->info0); |
645 | |
646 | status->u.desc_thresh_reached.link_desc_counter0 = |
647 | FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0, |
648 | desc->info1); |
649 | |
650 | status->u.desc_thresh_reached.link_desc_counter1 = |
651 | FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1, |
652 | desc->info2); |
653 | |
654 | status->u.desc_thresh_reached.link_desc_counter2 = |
655 | FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2, |
656 | desc->info3); |
657 | |
658 | status->u.desc_thresh_reached.link_desc_counter_sum = |
659 | FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM, |
660 | desc->info4); |
661 | } |
662 | |
663 | void ath11k_hal_reo_update_rx_reo_queue_status(struct ath11k_base *ab, |
664 | u32 *reo_desc, |
665 | struct hal_reo_status *status) |
666 | { |
667 | struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc; |
668 | struct hal_reo_status_hdr *desc = |
669 | (struct hal_reo_status_hdr *)tlv->value; |
670 | |
671 | status->uniform_hdr.cmd_num = |
672 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, |
673 | desc->info0); |
674 | status->uniform_hdr.cmd_status = |
675 | FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, |
676 | desc->info0); |
677 | } |
678 | |
679 | u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid) |
680 | { |
681 | u32 num_ext_desc; |
682 | |
683 | if (ba_window_size <= 1) { |
684 | if (tid != HAL_DESC_REO_NON_QOS_TID) |
685 | num_ext_desc = 1; |
686 | else |
687 | num_ext_desc = 0; |
688 | } else if (ba_window_size <= 105) { |
689 | num_ext_desc = 1; |
690 | } else if (ba_window_size <= 210) { |
691 | num_ext_desc = 2; |
692 | } else { |
693 | num_ext_desc = 3; |
694 | } |
695 | |
696 | return sizeof(struct hal_rx_reo_queue) + |
697 | (num_ext_desc * sizeof(struct hal_rx_reo_queue_ext)); |
698 | } |
699 | |
700 | void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, |
701 | u32 start_seq, enum hal_pn_type type) |
702 | { |
703 | struct hal_rx_reo_queue *qdesc = vaddr; |
704 | struct hal_rx_reo_queue_ext *ext_desc; |
705 | |
706 | memset(qdesc, 0, sizeof(*qdesc)); |
707 | |
708 | ath11k_hal_reo_set_desc_hdr(hdr: &qdesc->desc_hdr, HAL_DESC_REO_OWNED, |
709 | HAL_DESC_REO_QUEUE_DESC, |
710 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0); |
711 | |
712 | qdesc->rx_queue_num = FIELD_PREP(HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER, tid); |
713 | |
714 | qdesc->info0 = |
715 | FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_VLD, 1) | |
716 | FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER, 1) | |
717 | FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_AC, ath11k_tid_to_ac(tid)); |
718 | |
719 | if (ba_window_size < 1) |
720 | ba_window_size = 1; |
721 | |
722 | if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID) |
723 | ba_window_size++; |
724 | |
725 | if (ba_window_size == 1) |
726 | qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_RETRY, 1); |
727 | |
728 | qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE, |
729 | ba_window_size - 1); |
730 | switch (type) { |
731 | case HAL_PN_TYPE_NONE: |
732 | case HAL_PN_TYPE_WAPI_EVEN: |
733 | case HAL_PN_TYPE_WAPI_UNEVEN: |
734 | break; |
735 | case HAL_PN_TYPE_WPA: |
736 | qdesc->info0 |= |
737 | FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_CHECK, 1) | |
738 | FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_SIZE, |
739 | HAL_RX_REO_QUEUE_PN_SIZE_48); |
740 | break; |
741 | } |
742 | |
743 | /* TODO: Set Ignore ampdu flags based on BA window size and/or |
744 | * AMPDU capabilities |
745 | */ |
746 | qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG, 1); |
747 | |
748 | qdesc->info1 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SVLD, 0); |
749 | |
750 | if (start_seq <= 0xfff) |
751 | qdesc->info1 = FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SSN, |
752 | start_seq); |
753 | |
754 | if (tid == HAL_DESC_REO_NON_QOS_TID) |
755 | return; |
756 | |
757 | ext_desc = qdesc->ext_desc; |
758 | |
759 | /* TODO: HW queue descriptors are currently allocated for max BA |
760 | * window size for all QOS TIDs so that same descriptor can be used |
761 | * later when ADDBA request is received. This should be changed to |
762 | * allocate HW queue descriptors based on BA window size being |
763 | * negotiated (0 for non BA cases), and reallocate when BA window |
764 | * size changes and also send WMI message to FW to change the REO |
765 | * queue descriptor in Rx peer entry as part of dp_rx_tid_update. |
766 | */ |
767 | memset(ext_desc, 0, sizeof(*ext_desc)); |
768 | ath11k_hal_reo_set_desc_hdr(hdr: &ext_desc->desc_hdr, HAL_DESC_REO_OWNED, |
769 | HAL_DESC_REO_QUEUE_EXT_DESC, |
770 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1); |
771 | ext_desc++; |
772 | memset(ext_desc, 0, sizeof(*ext_desc)); |
773 | ath11k_hal_reo_set_desc_hdr(hdr: &ext_desc->desc_hdr, HAL_DESC_REO_OWNED, |
774 | HAL_DESC_REO_QUEUE_EXT_DESC, |
775 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2); |
776 | ext_desc++; |
777 | memset(ext_desc, 0, sizeof(*ext_desc)); |
778 | ath11k_hal_reo_set_desc_hdr(hdr: &ext_desc->desc_hdr, HAL_DESC_REO_OWNED, |
779 | HAL_DESC_REO_QUEUE_EXT_DESC, |
780 | REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3); |
781 | } |
782 | |
783 | void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, |
784 | struct hal_srng *srng) |
785 | { |
786 | struct hal_srng_params params; |
787 | struct hal_tlv_hdr *tlv; |
788 | struct hal_reo_get_queue_stats *desc; |
789 | int i, cmd_num = 1; |
790 | int entry_size; |
791 | u8 *entry; |
792 | |
793 | memset(¶ms, 0, sizeof(params)); |
794 | |
795 | entry_size = ath11k_hal_srng_get_entrysize(ab, ring_type: HAL_REO_CMD); |
796 | ath11k_hal_srng_get_params(ab, srng, params: ¶ms); |
797 | entry = (u8 *)params.ring_base_vaddr; |
798 | |
799 | for (i = 0; i < params.num_entries; i++) { |
800 | tlv = (struct hal_tlv_hdr *)entry; |
801 | desc = (struct hal_reo_get_queue_stats *)tlv->value; |
802 | desc->cmd.info0 = |
803 | FIELD_PREP(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, cmd_num++); |
804 | entry += entry_size; |
805 | } |
806 | } |
807 | |
808 | #define HAL_MAX_UL_MU_USERS 37 |
809 | static inline void |
810 | ath11k_hal_rx_handle_ofdma_info(void *rx_tlv, |
811 | struct hal_rx_user_status *rx_user_status) |
812 | { |
813 | struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv; |
814 | |
815 | rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6); |
816 | |
817 | rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info10); |
818 | } |
819 | |
820 | static inline void |
821 | ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo, |
822 | struct hal_rx_user_status *rx_user_status) |
823 | { |
824 | struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv; |
825 | |
826 | rx_user_status->mpdu_ok_byte_count = |
827 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT, |
828 | __le32_to_cpu(ppdu_end_user->info8)); |
829 | rx_user_status->mpdu_err_byte_count = |
830 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT, |
831 | __le32_to_cpu(ppdu_end_user->info9)); |
832 | } |
833 | |
834 | static inline void |
835 | ath11k_hal_rx_populate_mu_user_info(void *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info, |
836 | struct hal_rx_user_status *rx_user_status) |
837 | { |
838 | rx_user_status->ast_index = ppdu_info->ast_index; |
839 | rx_user_status->tid = ppdu_info->tid; |
840 | rx_user_status->tcp_msdu_count = |
841 | ppdu_info->tcp_msdu_count; |
842 | rx_user_status->udp_msdu_count = |
843 | ppdu_info->udp_msdu_count; |
844 | rx_user_status->other_msdu_count = |
845 | ppdu_info->other_msdu_count; |
846 | rx_user_status->frame_control = ppdu_info->frame_control; |
847 | rx_user_status->frame_control_info_valid = |
848 | ppdu_info->frame_control_info_valid; |
849 | rx_user_status->data_sequence_control_info_valid = |
850 | ppdu_info->data_sequence_control_info_valid; |
851 | rx_user_status->first_data_seq_ctrl = |
852 | ppdu_info->first_data_seq_ctrl; |
853 | rx_user_status->preamble_type = ppdu_info->preamble_type; |
854 | rx_user_status->ht_flags = ppdu_info->ht_flags; |
855 | rx_user_status->vht_flags = ppdu_info->vht_flags; |
856 | rx_user_status->he_flags = ppdu_info->he_flags; |
857 | rx_user_status->rs_flags = ppdu_info->rs_flags; |
858 | |
859 | rx_user_status->mpdu_cnt_fcs_ok = |
860 | ppdu_info->num_mpdu_fcs_ok; |
861 | rx_user_status->mpdu_cnt_fcs_err = |
862 | ppdu_info->num_mpdu_fcs_err; |
863 | |
864 | ath11k_hal_rx_populate_byte_count(rx_tlv, ppduinfo: ppdu_info, rx_user_status); |
865 | } |
866 | |
867 | static u16 ath11k_hal_rx_mpduinfo_get_peerid(struct ath11k_base *ab, |
868 | struct hal_rx_mpdu_info *mpdu_info) |
869 | { |
870 | return ab->hw_params.hw_ops->mpdu_info_get_peerid(mpdu_info); |
871 | } |
872 | |
873 | static enum hal_rx_mon_status |
874 | ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab, |
875 | struct hal_rx_mon_ppdu_info *ppdu_info, |
876 | u32 tlv_tag, u8 *tlv_data, u32 userid) |
877 | { |
878 | u32 info0, info1, value; |
879 | u8 he_dcm = 0, he_stbc = 0; |
880 | u16 he_gi = 0, he_ltf = 0; |
881 | |
882 | switch (tlv_tag) { |
883 | case HAL_RX_PPDU_START: { |
884 | struct hal_rx_ppdu_start *ppdu_start = |
885 | (struct hal_rx_ppdu_start *)tlv_data; |
886 | |
887 | ppdu_info->ppdu_id = |
888 | FIELD_GET(HAL_RX_PPDU_START_INFO0_PPDU_ID, |
889 | __le32_to_cpu(ppdu_start->info0)); |
890 | ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num); |
891 | ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts); |
892 | break; |
893 | } |
894 | case HAL_RX_PPDU_END_USER_STATS: { |
895 | struct hal_rx_ppdu_end_user_stats *eu_stats = |
896 | (struct hal_rx_ppdu_end_user_stats *)tlv_data; |
897 | |
898 | info0 = __le32_to_cpu(eu_stats->info0); |
899 | info1 = __le32_to_cpu(eu_stats->info1); |
900 | |
901 | ppdu_info->ast_index = |
902 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX, |
903 | __le32_to_cpu(eu_stats->info2)); |
904 | ppdu_info->tid = |
905 | ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP, |
906 | __le32_to_cpu(eu_stats->info7))) - 1; |
907 | ppdu_info->tcp_msdu_count = |
908 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT, |
909 | __le32_to_cpu(eu_stats->info4)); |
910 | ppdu_info->udp_msdu_count = |
911 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT, |
912 | __le32_to_cpu(eu_stats->info4)); |
913 | ppdu_info->other_msdu_count = |
914 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT, |
915 | __le32_to_cpu(eu_stats->info5)); |
916 | ppdu_info->tcp_ack_msdu_count = |
917 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT, |
918 | __le32_to_cpu(eu_stats->info5)); |
919 | ppdu_info->preamble_type = |
920 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE, info1); |
921 | ppdu_info->num_mpdu_fcs_ok = |
922 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK, |
923 | info1); |
924 | ppdu_info->num_mpdu_fcs_err = |
925 | FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR, |
926 | info0); |
927 | switch (ppdu_info->preamble_type) { |
928 | case HAL_RX_PREAMBLE_11N: |
929 | ppdu_info->ht_flags = 1; |
930 | break; |
931 | case HAL_RX_PREAMBLE_11AC: |
932 | ppdu_info->vht_flags = 1; |
933 | break; |
934 | case HAL_RX_PREAMBLE_11AX: |
935 | ppdu_info->he_flags = 1; |
936 | break; |
937 | default: |
938 | break; |
939 | } |
940 | |
941 | if (userid < HAL_MAX_UL_MU_USERS) { |
942 | struct hal_rx_user_status *rxuser_stats = |
943 | &ppdu_info->userstats; |
944 | |
945 | ath11k_hal_rx_handle_ofdma_info(rx_tlv: tlv_data, rx_user_status: rxuser_stats); |
946 | ath11k_hal_rx_populate_mu_user_info(rx_tlv: tlv_data, ppdu_info, |
947 | rx_user_status: rxuser_stats); |
948 | } |
949 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] = |
950 | __le32_to_cpu(eu_stats->rsvd1[0]); |
951 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] = |
952 | __le32_to_cpu(eu_stats->rsvd1[1]); |
953 | |
954 | break; |
955 | } |
956 | case HAL_RX_PPDU_END_USER_STATS_EXT: { |
957 | struct hal_rx_ppdu_end_user_stats_ext *eu_stats = |
958 | (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data; |
959 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1; |
960 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2; |
961 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3; |
962 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4; |
963 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5; |
964 | ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6; |
965 | break; |
966 | } |
967 | case HAL_PHYRX_HT_SIG: { |
968 | struct hal_rx_ht_sig_info *ht_sig = |
969 | (struct hal_rx_ht_sig_info *)tlv_data; |
970 | |
971 | info0 = __le32_to_cpu(ht_sig->info0); |
972 | info1 = __le32_to_cpu(ht_sig->info1); |
973 | |
974 | ppdu_info->mcs = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_MCS, info0); |
975 | ppdu_info->bw = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_BW, info0); |
976 | ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC, |
977 | info1); |
978 | ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1); |
979 | ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI; |
980 | |
981 | switch (ppdu_info->mcs) { |
982 | case 0 ... 7: |
983 | ppdu_info->nss = 1; |
984 | break; |
985 | case 8 ... 15: |
986 | ppdu_info->nss = 2; |
987 | break; |
988 | case 16 ... 23: |
989 | ppdu_info->nss = 3; |
990 | break; |
991 | case 24 ... 31: |
992 | ppdu_info->nss = 4; |
993 | break; |
994 | } |
995 | |
996 | if (ppdu_info->nss > 1) |
997 | ppdu_info->mcs = ppdu_info->mcs % 8; |
998 | |
999 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
1000 | break; |
1001 | } |
1002 | case HAL_PHYRX_L_SIG_B: { |
1003 | struct hal_rx_lsig_b_info *lsigb = |
1004 | (struct hal_rx_lsig_b_info *)tlv_data; |
1005 | |
1006 | ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE, |
1007 | __le32_to_cpu(lsigb->info0)); |
1008 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
1009 | break; |
1010 | } |
1011 | case HAL_PHYRX_L_SIG_A: { |
1012 | struct hal_rx_lsig_a_info *lsiga = |
1013 | (struct hal_rx_lsig_a_info *)tlv_data; |
1014 | |
1015 | ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE, |
1016 | __le32_to_cpu(lsiga->info0)); |
1017 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
1018 | break; |
1019 | } |
1020 | case HAL_PHYRX_VHT_SIG_A: { |
1021 | struct hal_rx_vht_sig_a_info *vht_sig = |
1022 | (struct hal_rx_vht_sig_a_info *)tlv_data; |
1023 | u32 nsts; |
1024 | u32 group_id; |
1025 | u8 gi_setting; |
1026 | |
1027 | info0 = __le32_to_cpu(vht_sig->info0); |
1028 | info1 = __le32_to_cpu(vht_sig->info1); |
1029 | |
1030 | ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, |
1031 | info1); |
1032 | ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS, |
1033 | info1); |
1034 | gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING, |
1035 | info1); |
1036 | switch (gi_setting) { |
1037 | case HAL_RX_VHT_SIG_A_NORMAL_GI: |
1038 | ppdu_info->gi = HAL_RX_GI_0_8_US; |
1039 | break; |
1040 | case HAL_RX_VHT_SIG_A_SHORT_GI: |
1041 | case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY: |
1042 | ppdu_info->gi = HAL_RX_GI_0_4_US; |
1043 | break; |
1044 | } |
1045 | |
1046 | ppdu_info->is_stbc = info0 & HAL_RX_VHT_SIG_A_INFO_INFO0_STBC; |
1047 | nsts = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS, info0); |
1048 | if (ppdu_info->is_stbc && nsts > 0) |
1049 | nsts = ((nsts + 1) >> 1) - 1; |
1050 | |
1051 | ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK) + 1; |
1052 | ppdu_info->bw = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_BW, |
1053 | info0); |
1054 | ppdu_info->beamformed = info1 & |
1055 | HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED; |
1056 | group_id = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID, |
1057 | info0); |
1058 | if (group_id == 0 || group_id == 63) |
1059 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
1060 | else |
1061 | ppdu_info->reception_type = |
1062 | HAL_RX_RECEPTION_TYPE_MU_MIMO; |
1063 | ppdu_info->vht_flag_values5 = group_id; |
1064 | ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) | |
1065 | ppdu_info->nss); |
1066 | ppdu_info->vht_flag_values2 = ppdu_info->bw; |
1067 | ppdu_info->vht_flag_values4 = |
1068 | FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, info1); |
1069 | break; |
1070 | } |
1071 | case HAL_PHYRX_HE_SIG_A_SU: { |
1072 | struct hal_rx_he_sig_a_su_info *he_sig_a = |
1073 | (struct hal_rx_he_sig_a_su_info *)tlv_data; |
1074 | |
1075 | ppdu_info->he_flags = 1; |
1076 | info0 = __le32_to_cpu(he_sig_a->info0); |
1077 | info1 = __le32_to_cpu(he_sig_a->info1); |
1078 | |
1079 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND, info0); |
1080 | |
1081 | if (value == 0) |
1082 | ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG; |
1083 | else |
1084 | ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU; |
1085 | |
1086 | ppdu_info->he_data1 |= |
1087 | IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | |
1088 | IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN | |
1089 | IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | |
1090 | IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | |
1091 | IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | |
1092 | IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN | |
1093 | IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | |
1094 | IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | |
1095 | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN | |
1096 | IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN; |
1097 | |
1098 | ppdu_info->he_data2 |= |
1099 | IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN | |
1100 | IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN | |
1101 | IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | |
1102 | IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | |
1103 | IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN | |
1104 | IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | |
1105 | IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN; |
1106 | |
1107 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR, info0); |
1108 | ppdu_info->he_data3 = |
1109 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value); |
1110 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE, info0); |
1111 | ppdu_info->he_data3 |= |
1112 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE, value); |
1113 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG, info0); |
1114 | ppdu_info->he_data3 |= |
1115 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value); |
1116 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, info0); |
1117 | ppdu_info->mcs = value; |
1118 | ppdu_info->he_data3 |= |
1119 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, value); |
1120 | |
1121 | he_dcm = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM, info0); |
1122 | ppdu_info->dcm = he_dcm; |
1123 | ppdu_info->he_data3 |= |
1124 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, he_dcm); |
1125 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info1); |
1126 | ppdu_info->ldpc = (value == HAL_RX_SU_MU_CODING_LDPC) ? 1 : 0; |
1127 | ppdu_info->he_data3 |= |
1128 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value); |
1129 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA, info1); |
1130 | ppdu_info->he_data3 |= |
1131 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value); |
1132 | he_stbc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC, info1); |
1133 | ppdu_info->is_stbc = he_stbc; |
1134 | ppdu_info->he_data3 |= |
1135 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, he_stbc); |
1136 | |
1137 | /* data4 */ |
1138 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE, info0); |
1139 | ppdu_info->he_data4 = |
1140 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value); |
1141 | |
1142 | /* data5 */ |
1143 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, info0); |
1144 | ppdu_info->bw = value; |
1145 | ppdu_info->he_data5 = |
1146 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value); |
1147 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, info0); |
1148 | switch (value) { |
1149 | case 0: |
1150 | he_gi = HE_GI_0_8; |
1151 | he_ltf = HE_LTF_1_X; |
1152 | break; |
1153 | case 1: |
1154 | he_gi = HE_GI_0_8; |
1155 | he_ltf = HE_LTF_2_X; |
1156 | break; |
1157 | case 2: |
1158 | he_gi = HE_GI_1_6; |
1159 | he_ltf = HE_LTF_2_X; |
1160 | break; |
1161 | case 3: |
1162 | if (he_dcm && he_stbc) { |
1163 | he_gi = HE_GI_0_8; |
1164 | he_ltf = HE_LTF_4_X; |
1165 | } else { |
1166 | he_gi = HE_GI_3_2; |
1167 | he_ltf = HE_LTF_4_X; |
1168 | } |
1169 | break; |
1170 | } |
1171 | ppdu_info->gi = he_gi; |
1172 | he_gi = (he_gi != 0) ? he_gi - 1 : 0; |
1173 | ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi); |
1174 | ppdu_info->ltf_size = he_ltf; |
1175 | ppdu_info->he_data5 |= |
1176 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE, |
1177 | (he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf); |
1178 | |
1179 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); |
1180 | ppdu_info->he_data5 |= |
1181 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value); |
1182 | |
1183 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR, info1); |
1184 | ppdu_info->he_data5 |= |
1185 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value); |
1186 | |
1187 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF, info1); |
1188 | ppdu_info->beamformed = value; |
1189 | ppdu_info->he_data5 |= |
1190 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_TXBF, value); |
1191 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM, info1); |
1192 | ppdu_info->he_data5 |= |
1193 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value); |
1194 | |
1195 | /* data6 */ |
1196 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0); |
1197 | value++; |
1198 | ppdu_info->nss = value; |
1199 | ppdu_info->he_data6 = |
1200 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_NSTS, value); |
1201 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND, info1); |
1202 | ppdu_info->he_data6 |= |
1203 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value); |
1204 | value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION, info1); |
1205 | ppdu_info->he_data6 |= |
1206 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value); |
1207 | |
1208 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; |
1209 | break; |
1210 | } |
1211 | case HAL_PHYRX_HE_SIG_A_MU_DL: { |
1212 | struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl = |
1213 | (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data; |
1214 | |
1215 | info0 = __le32_to_cpu(he_sig_a_mu_dl->info0); |
1216 | info1 = __le32_to_cpu(he_sig_a_mu_dl->info1); |
1217 | |
1218 | ppdu_info->he_mu_flags = 1; |
1219 | |
1220 | ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU; |
1221 | ppdu_info->he_data1 |= |
1222 | IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN | |
1223 | IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN | |
1224 | IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | |
1225 | IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN | |
1226 | IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN | |
1227 | IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN; |
1228 | |
1229 | ppdu_info->he_data2 = |
1230 | IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN | |
1231 | IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN | |
1232 | IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | |
1233 | IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN | |
1234 | IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN | |
1235 | IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN; |
1236 | |
1237 | /*data3*/ |
1238 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_BSS_COLOR, info0); |
1239 | ppdu_info->he_data3 = |
1240 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value); |
1241 | |
1242 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_UL_FLAG, info0); |
1243 | ppdu_info->he_data3 |= |
1244 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value); |
1245 | |
1246 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_LDPC_EXTRA, info1); |
1247 | ppdu_info->he_data3 |= |
1248 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value); |
1249 | |
1250 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC, info1); |
1251 | he_stbc = value; |
1252 | ppdu_info->he_data3 |= |
1253 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, value); |
1254 | |
1255 | /*data4*/ |
1256 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_SPATIAL_REUSE, info0); |
1257 | ppdu_info->he_data4 = |
1258 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value); |
1259 | |
1260 | /*data5*/ |
1261 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0); |
1262 | ppdu_info->bw = value; |
1263 | ppdu_info->he_data5 = |
1264 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value); |
1265 | |
1266 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, info0); |
1267 | switch (value) { |
1268 | case 0: |
1269 | he_gi = HE_GI_0_8; |
1270 | he_ltf = HE_LTF_4_X; |
1271 | break; |
1272 | case 1: |
1273 | he_gi = HE_GI_0_8; |
1274 | he_ltf = HE_LTF_2_X; |
1275 | break; |
1276 | case 2: |
1277 | he_gi = HE_GI_1_6; |
1278 | he_ltf = HE_LTF_2_X; |
1279 | break; |
1280 | case 3: |
1281 | he_gi = HE_GI_3_2; |
1282 | he_ltf = HE_LTF_4_X; |
1283 | break; |
1284 | } |
1285 | ppdu_info->gi = he_gi; |
1286 | he_gi = (he_gi != 0) ? he_gi - 1 : 0; |
1287 | ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi); |
1288 | ppdu_info->ltf_size = he_ltf; |
1289 | ppdu_info->he_data5 |= |
1290 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE, |
1291 | (he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf); |
1292 | |
1293 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_NUM_LTF_SYMB, info1); |
1294 | ppdu_info->he_data5 |= |
1295 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value); |
1296 | |
1297 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_FACTOR, |
1298 | info1); |
1299 | ppdu_info->he_data5 |= |
1300 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value); |
1301 | |
1302 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_PE_DISAM, |
1303 | info1); |
1304 | ppdu_info->he_data5 |= |
1305 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value); |
1306 | |
1307 | /*data6*/ |
1308 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DOPPLER_INDICATION, |
1309 | info0); |
1310 | ppdu_info->he_data6 |= |
1311 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value); |
1312 | |
1313 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXOP_DURATION, info1); |
1314 | ppdu_info->he_data6 |= |
1315 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value); |
1316 | |
1317 | /* HE-MU Flags */ |
1318 | /* HE-MU-flags1 */ |
1319 | ppdu_info->he_flags1 = |
1320 | IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN | |
1321 | IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN | |
1322 | IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN | |
1323 | IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN | |
1324 | IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN; |
1325 | |
1326 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_MCS_OF_SIGB, info0); |
1327 | ppdu_info->he_flags1 |= |
1328 | FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN, |
1329 | value); |
1330 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DCM_OF_SIGB, info0); |
1331 | ppdu_info->he_flags1 |= |
1332 | FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN, |
1333 | value); |
1334 | |
1335 | /* HE-MU-flags2 */ |
1336 | ppdu_info->he_flags2 = |
1337 | IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN; |
1338 | |
1339 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0); |
1340 | ppdu_info->he_flags2 |= |
1341 | FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW, |
1342 | value); |
1343 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_COMP_MODE_SIGB, info0); |
1344 | ppdu_info->he_flags2 |= |
1345 | FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP, value); |
1346 | value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_NUM_SIGB_SYMB, info0); |
1347 | value = value - 1; |
1348 | ppdu_info->he_flags2 |= |
1349 | FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS, |
1350 | value); |
1351 | |
1352 | ppdu_info->is_stbc = info1 & |
1353 | HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC; |
1354 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; |
1355 | break; |
1356 | } |
1357 | case HAL_PHYRX_HE_SIG_B1_MU: { |
1358 | struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu = |
1359 | (struct hal_rx_he_sig_b1_mu_info *)tlv_data; |
1360 | u16 ru_tones; |
1361 | |
1362 | info0 = __le32_to_cpu(he_sig_b1_mu->info0); |
1363 | |
1364 | ru_tones = FIELD_GET(HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION, |
1365 | info0); |
1366 | ppdu_info->ru_alloc = |
1367 | ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(ru_phy: ru_tones); |
1368 | ppdu_info->he_RU[0] = ru_tones; |
1369 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; |
1370 | break; |
1371 | } |
1372 | case HAL_PHYRX_HE_SIG_B2_MU: { |
1373 | struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu = |
1374 | (struct hal_rx_he_sig_b2_mu_info *)tlv_data; |
1375 | |
1376 | info0 = __le32_to_cpu(he_sig_b2_mu->info0); |
1377 | |
1378 | ppdu_info->he_data1 |= IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | |
1379 | IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN; |
1380 | |
1381 | ppdu_info->mcs = |
1382 | FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, info0); |
1383 | ppdu_info->he_data3 |= |
1384 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs); |
1385 | |
1386 | value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, info0); |
1387 | ppdu_info->ldpc = value; |
1388 | ppdu_info->he_data3 |= |
1389 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value); |
1390 | |
1391 | value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID, info0); |
1392 | ppdu_info->he_data4 |= |
1393 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value); |
1394 | |
1395 | ppdu_info->nss = |
1396 | FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, info0) + 1; |
1397 | break; |
1398 | } |
1399 | case HAL_PHYRX_HE_SIG_B2_OFDMA: { |
1400 | struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma = |
1401 | (struct hal_rx_he_sig_b2_ofdma_info *)tlv_data; |
1402 | |
1403 | info0 = __le32_to_cpu(he_sig_b2_ofdma->info0); |
1404 | |
1405 | ppdu_info->he_data1 |= |
1406 | IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN | |
1407 | IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN | |
1408 | IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN; |
1409 | |
1410 | /* HE-data2 */ |
1411 | ppdu_info->he_data2 |= IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN; |
1412 | |
1413 | ppdu_info->mcs = |
1414 | FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS, |
1415 | info0); |
1416 | ppdu_info->he_data3 |= |
1417 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs); |
1418 | |
1419 | value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM, info0); |
1420 | he_dcm = value; |
1421 | ppdu_info->he_data3 |= |
1422 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, value); |
1423 | |
1424 | value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, info0); |
1425 | ppdu_info->ldpc = value; |
1426 | ppdu_info->he_data3 |= |
1427 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value); |
1428 | |
1429 | /* HE-data4 */ |
1430 | value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID, info0); |
1431 | ppdu_info->he_data4 |= |
1432 | FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value); |
1433 | |
1434 | ppdu_info->nss = |
1435 | FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS, |
1436 | info0) + 1; |
1437 | ppdu_info->beamformed = |
1438 | info0 & HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF; |
1439 | ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; |
1440 | break; |
1441 | } |
1442 | case HAL_PHYRX_RSSI_LEGACY: { |
1443 | int i; |
1444 | bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, |
1445 | ab->wmi_ab.svc_map); |
1446 | struct hal_rx_phyrx_rssi_legacy_info * = |
1447 | (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data; |
1448 | |
1449 | /* TODO: Please note that the combined rssi will not be accurate |
1450 | * in MU case. Rssi in MU needs to be retrieved from |
1451 | * PHYRX_OTHER_RECEIVE_INFO TLV. |
1452 | */ |
1453 | ppdu_info->rssi_comb = |
1454 | FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB, |
1455 | __le32_to_cpu(rssi->info0)); |
1456 | |
1457 | if (db2dbm) { |
1458 | for (i = 0; i < ARRAY_SIZE(rssi->preamble); i++) { |
1459 | ppdu_info->rssi_chain_pri20[i] = |
1460 | le32_get_bits(v: rssi->preamble[i].rssi_2040, |
1461 | HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20); |
1462 | } |
1463 | } |
1464 | break; |
1465 | } |
1466 | case HAL_RX_MPDU_START: { |
1467 | struct hal_rx_mpdu_info *mpdu_info = |
1468 | (struct hal_rx_mpdu_info *)tlv_data; |
1469 | u16 peer_id; |
1470 | |
1471 | peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info); |
1472 | if (peer_id) |
1473 | ppdu_info->peer_id = peer_id; |
1474 | break; |
1475 | } |
1476 | case HAL_RXPCU_PPDU_END_INFO: { |
1477 | struct hal_rx_ppdu_end_duration *ppdu_rx_duration = |
1478 | (struct hal_rx_ppdu_end_duration *)tlv_data; |
1479 | ppdu_info->rx_duration = |
1480 | FIELD_GET(HAL_RX_PPDU_END_DURATION, |
1481 | __le32_to_cpu(ppdu_rx_duration->info0)); |
1482 | ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]); |
1483 | ppdu_info->tsft = (ppdu_info->tsft << 32) | |
1484 | __le32_to_cpu(ppdu_rx_duration->rsvd0[0]); |
1485 | break; |
1486 | } |
1487 | case HAL_DUMMY: |
1488 | return HAL_RX_MON_STATUS_BUF_DONE; |
1489 | case HAL_RX_PPDU_END_STATUS_DONE: |
1490 | case 0: |
1491 | return HAL_RX_MON_STATUS_PPDU_DONE; |
1492 | default: |
1493 | break; |
1494 | } |
1495 | |
1496 | return HAL_RX_MON_STATUS_PPDU_NOT_DONE; |
1497 | } |
1498 | |
1499 | enum hal_rx_mon_status |
1500 | ath11k_hal_rx_parse_mon_status(struct ath11k_base *ab, |
1501 | struct hal_rx_mon_ppdu_info *ppdu_info, |
1502 | struct sk_buff *skb) |
1503 | { |
1504 | struct hal_tlv_hdr *tlv; |
1505 | enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE; |
1506 | u16 tlv_tag; |
1507 | u16 tlv_len; |
1508 | u32 tlv_userid = 0; |
1509 | u8 *ptr = skb->data; |
1510 | |
1511 | do { |
1512 | tlv = (struct hal_tlv_hdr *)ptr; |
1513 | tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl); |
1514 | tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl); |
1515 | tlv_userid = FIELD_GET(HAL_TLV_USR_ID, tlv->tl); |
1516 | ptr += sizeof(*tlv); |
1517 | |
1518 | /* The actual length of PPDU_END is the combined length of many PHY |
1519 | * TLVs that follow. Skip the TLV header and |
1520 | * rx_rxpcu_classification_overview that follows the header to get to |
1521 | * next TLV. |
1522 | */ |
1523 | if (tlv_tag == HAL_RX_PPDU_END) |
1524 | tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview); |
1525 | |
1526 | hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info, |
1527 | tlv_tag, tlv_data: ptr, userid: tlv_userid); |
1528 | ptr += tlv_len; |
1529 | ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN); |
1530 | |
1531 | if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE) |
1532 | break; |
1533 | } while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE); |
1534 | |
1535 | return hal_status; |
1536 | } |
1537 | |
1538 | void ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr, |
1539 | u32 *sw_cookie, void **pp_buf_addr, |
1540 | u8 *rbm, u32 *msdu_cnt) |
1541 | { |
1542 | struct hal_reo_entrance_ring *reo_ent_ring = rx_desc; |
1543 | struct ath11k_buffer_addr *buf_addr_info; |
1544 | struct rx_mpdu_desc *rx_mpdu_desc_info_details; |
1545 | |
1546 | rx_mpdu_desc_info_details = |
1547 | (struct rx_mpdu_desc *)&reo_ent_ring->rx_mpdu_info; |
1548 | |
1549 | *msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT, |
1550 | rx_mpdu_desc_info_details->info0); |
1551 | |
1552 | buf_addr_info = (struct ath11k_buffer_addr *)&reo_ent_ring->buf_addr_info; |
1553 | |
1554 | *paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, |
1555 | buf_addr_info->info1)) << 32) | |
1556 | FIELD_GET(BUFFER_ADDR_INFO0_ADDR, |
1557 | buf_addr_info->info0); |
1558 | |
1559 | *sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, |
1560 | buf_addr_info->info1); |
1561 | *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, |
1562 | buf_addr_info->info1); |
1563 | |
1564 | *pp_buf_addr = (void *)buf_addr_info; |
1565 | } |
1566 | |
1567 | void |
1568 | ath11k_hal_rx_sw_mon_ring_buf_paddr_get(void *rx_desc, |
1569 | struct hal_sw_mon_ring_entries *sw_mon_entries) |
1570 | { |
1571 | struct hal_sw_monitor_ring *sw_mon_ring = rx_desc; |
1572 | struct ath11k_buffer_addr *buf_addr_info; |
1573 | struct ath11k_buffer_addr *status_buf_addr_info; |
1574 | struct rx_mpdu_desc *rx_mpdu_desc_info_details; |
1575 | |
1576 | rx_mpdu_desc_info_details = &sw_mon_ring->rx_mpdu_info; |
1577 | |
1578 | sw_mon_entries->msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT, |
1579 | rx_mpdu_desc_info_details->info0); |
1580 | |
1581 | buf_addr_info = &sw_mon_ring->buf_addr_info; |
1582 | status_buf_addr_info = &sw_mon_ring->status_buf_addr_info; |
1583 | |
1584 | sw_mon_entries->mon_dst_paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, |
1585 | buf_addr_info->info1)) << 32) | |
1586 | FIELD_GET(BUFFER_ADDR_INFO0_ADDR, |
1587 | buf_addr_info->info0); |
1588 | |
1589 | sw_mon_entries->mon_status_paddr = |
1590 | (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, |
1591 | status_buf_addr_info->info1)) << 32) | |
1592 | FIELD_GET(BUFFER_ADDR_INFO0_ADDR, |
1593 | status_buf_addr_info->info0); |
1594 | |
1595 | sw_mon_entries->mon_dst_sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, |
1596 | buf_addr_info->info1); |
1597 | |
1598 | sw_mon_entries->mon_status_sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, |
1599 | status_buf_addr_info->info1); |
1600 | |
1601 | sw_mon_entries->status_buf_count = FIELD_GET(HAL_SW_MON_RING_INFO0_STATUS_BUF_CNT, |
1602 | sw_mon_ring->info0); |
1603 | |
1604 | sw_mon_entries->dst_buf_addr_info = buf_addr_info; |
1605 | sw_mon_entries->status_buf_addr_info = status_buf_addr_info; |
1606 | |
1607 | sw_mon_entries->ppdu_id = |
1608 | FIELD_GET(HAL_SW_MON_RING_INFO1_PHY_PPDU_ID, sw_mon_ring->info1); |
1609 | } |
1610 | |