1 /*
2 * Copyright (c) 2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE
16 */
17 #ifndef _HAL_5332_TX_H_
18 #define _HAL_5332_TX_H_
19
20 #include "tcl_data_cmd.h"
21 #include "phyrx_rssi_legacy.h"
22 #include "hal_internal.h"
23 #include "qdf_trace.h"
24 #include "hal_rx.h"
25 #include "hal_tx.h"
26 #include "hal_api_mon.h"
27 #include <hal_be_tx.h>
28
29 #define DSCP_TID_TABLE_SIZE 24
30 #define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4)
31 #define HAL_TX_NUM_DSCP_REGISTER_SIZE 32
32
33 /**
34 * hal_tx_set_dscp_tid_map_5332() - Configure default DSCP to TID map table
35 * @hal_soc: HAL SoC context
36 * @map: DSCP-TID mapping table
37 * @id: mapping table ID - 0-31
38 *
39 * DSCP are mapped to 8 TID values using TID values programmed
40 * in any of the 32 DSCP_TID_MAPS (id = 0-31).
41 *
42 * Return: none
43 */
hal_tx_set_dscp_tid_map_5332(struct hal_soc * hal_soc,uint8_t * map,uint8_t id)44 static void hal_tx_set_dscp_tid_map_5332(struct hal_soc *hal_soc, uint8_t *map,
45 uint8_t id)
46 {
47 int i;
48 uint32_t addr, cmn_reg_addr;
49 uint32_t value = 0, regval;
50 uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0;
51
52 struct hal_soc *soc = (struct hal_soc *)hal_soc;
53
54 if (id >= HAL_MAX_HW_DSCP_TID_V2_MAPS_5332)
55 return;
56
57 cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(
58 MAC_TCL_REG_REG_BASE);
59
60 addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR(
61 MAC_TCL_REG_REG_BASE,
62 id * NUM_WORDS_PER_DSCP_TID_TABLE);
63
64 /* Enable read/write access */
65 regval = HAL_REG_READ(soc, cmn_reg_addr);
66 regval |=
67 (1 <<
68 HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT);
69
70 HAL_REG_WRITE(soc, cmn_reg_addr, regval);
71
72 /* Write 8 (24 bits) DSCP-TID mappings in each iteration */
73 for (i = 0; i < 64; i += 8) {
74 value = (map[i] |
75 (map[i + 1] << 0x3) |
76 (map[i + 2] << 0x6) |
77 (map[i + 3] << 0x9) |
78 (map[i + 4] << 0xc) |
79 (map[i + 5] << 0xf) |
80 (map[i + 6] << 0x12) |
81 (map[i + 7] << 0x15));
82
83 qdf_mem_copy(&val[cnt], (void *)&value, 3);
84 cnt += 3;
85 }
86
87 for (i = 0; i < DSCP_TID_TABLE_SIZE; i += 4) {
88 regval = *(uint32_t *)(val + i);
89 HAL_REG_WRITE(soc, addr,
90 (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK));
91 addr += 4;
92 }
93
94 /* Disable read/write access */
95 regval = HAL_REG_READ(soc, cmn_reg_addr);
96 regval &=
97 ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK);
98
99 HAL_REG_WRITE(soc, cmn_reg_addr, regval);
100 }
101
102 /**
103 * hal_tx_update_dscp_tid_5332() - Update the dscp tid map table as updated
104 * by the user
105 * @soc: HAL SoC context
106 * @tid: TID
107 * @id: MAP ID
108 * @dscp: DSCP_TID map index
109 *
110 * Return: void
111 */
hal_tx_update_dscp_tid_5332(struct hal_soc * soc,uint8_t tid,uint8_t id,uint8_t dscp)112 static void hal_tx_update_dscp_tid_5332(struct hal_soc *soc, uint8_t tid,
113 uint8_t id, uint8_t dscp)
114 {
115 uint32_t addr, addr1, cmn_reg_addr;
116 uint32_t start_value = 0, end_value = 0;
117 uint32_t regval;
118 uint8_t end_bits = 0;
119 uint8_t start_bits = 0;
120 uint32_t start_index, end_index;
121
122 cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(
123 MAC_TCL_REG_REG_BASE);
124
125 addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR(
126 MAC_TCL_REG_REG_BASE,
127 id * NUM_WORDS_PER_DSCP_TID_TABLE);
128
129 start_index = dscp * HAL_TX_BITS_PER_TID;
130 end_index = (start_index + (HAL_TX_BITS_PER_TID - 1))
131 % HAL_TX_NUM_DSCP_REGISTER_SIZE;
132 start_index = start_index % HAL_TX_NUM_DSCP_REGISTER_SIZE;
133 addr += (4 * ((dscp * HAL_TX_BITS_PER_TID) /
134 HAL_TX_NUM_DSCP_REGISTER_SIZE));
135
136 if (end_index < start_index) {
137 end_bits = end_index + 1;
138 start_bits = HAL_TX_BITS_PER_TID - end_bits;
139 start_value = tid << start_index;
140 end_value = tid >> start_bits;
141 addr1 = addr + 4;
142 } else {
143 start_bits = HAL_TX_BITS_PER_TID - end_bits;
144 start_value = tid << start_index;
145 addr1 = 0;
146 }
147
148 /* Enable read/write access */
149 regval = HAL_REG_READ(soc, cmn_reg_addr);
150 regval |=
151 (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT);
152
153 HAL_REG_WRITE(soc, cmn_reg_addr, regval);
154
155 regval = HAL_REG_READ(soc, addr);
156
157 if (end_index < start_index)
158 regval &= (~0) >> start_bits;
159 else
160 regval &= ~(7 << start_index);
161
162 regval |= start_value;
163
164 HAL_REG_WRITE(soc, addr, (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK));
165
166 if (addr1) {
167 regval = HAL_REG_READ(soc, addr1);
168 regval &= (~0) << end_bits;
169 regval |= end_value;
170
171 HAL_REG_WRITE(soc, addr1, (regval &
172 HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK));
173 }
174
175 /* Disable read/write access */
176 regval = HAL_REG_READ(soc, cmn_reg_addr);
177 regval &=
178 ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK);
179 HAL_REG_WRITE(soc, cmn_reg_addr, regval);
180 }
181
182 #ifdef DP_TX_IMPLICIT_RBM_MAPPING
183
184 #define RBM_MAPPING_BMSK HWIO_TCL_R0_RBM_MAPPING0_SW2TCL1_RING_BMSK
185 #define RBM_MAPPING_SHFT HWIO_TCL_R0_RBM_MAPPING0_SW2TCL2_RING_SHFT
186
187 #define RBM_TCL_CMD_CREDIT_OFFSET \
188 (HWIO_TCL_R0_RBM_MAPPING0_SW2TCL_CREDIT_RING_SHFT >> 2)
189
190 /**
191 * hal_tx_config_rbm_mapping_be_5332() - Update return buffer manager ring id
192 * @hal_soc_hdl: HAL SoC context
193 * @hal_ring_hdl: Source ring pointer
194 * @rbm_id: return buffer manager ring id
195 *
196 * Return: void
197 */
198 static inline void
hal_tx_config_rbm_mapping_be_5332(hal_soc_handle_t hal_soc_hdl,hal_ring_handle_t hal_ring_hdl,uint8_t rbm_id)199 hal_tx_config_rbm_mapping_be_5332(hal_soc_handle_t hal_soc_hdl,
200 hal_ring_handle_t hal_ring_hdl,
201 uint8_t rbm_id)
202 {
203 struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
204 struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
205 uint32_t reg_addr = 0;
206 uint32_t reg_val = 0;
207 uint32_t val = 0;
208 uint8_t ring_num;
209 enum hal_ring_type ring_type;
210
211 ring_type = srng->ring_type;
212 ring_num = hal_soc->hw_srng_table[ring_type].start_ring_id;
213 ring_num = srng->ring_id - ring_num;
214
215 reg_addr = HWIO_TCL_R0_RBM_MAPPING0_ADDR(MAC_TCL_REG_REG_BASE);
216
217 if (ring_type == TCL_CMD_CREDIT)
218 ring_num = ring_num + RBM_TCL_CMD_CREDIT_OFFSET;
219
220 /* get current value stored in register address */
221 val = HAL_REG_READ(hal_soc, reg_addr);
222
223 /* mask out other stored value */
224 val &= (~(RBM_MAPPING_BMSK << (RBM_MAPPING_SHFT * ring_num)));
225
226 reg_val = val | ((RBM_MAPPING_BMSK & rbm_id) <<
227 (RBM_MAPPING_SHFT * ring_num));
228
229 /* write rbm mapped value to register address */
230 HAL_REG_WRITE(hal_soc, reg_addr, reg_val);
231 }
232 #else
233 static inline void
hal_tx_config_rbm_mapping_be_5332(hal_soc_handle_t hal_soc_hdl,hal_ring_handle_t hal_ring_hdl,uint8_t rbm_id)234 hal_tx_config_rbm_mapping_be_5332(hal_soc_handle_t hal_soc_hdl,
235 hal_ring_handle_t hal_ring_hdl,
236 uint8_t rbm_id)
237 {
238 }
239 #endif
240
241 /**
242 * hal_tx_init_cmd_credit_ring_5332() - Initialize command/credit SRNG
243 * @hal_soc_hdl: Handle to HAL SoC structure
244 * @hal_ring_hdl: Handle to HAL SRNG structure
245 *
246 * Return: none
247 */
248 static inline void
hal_tx_init_cmd_credit_ring_5332(hal_soc_handle_t hal_soc_hdl,hal_ring_handle_t hal_ring_hdl)249 hal_tx_init_cmd_credit_ring_5332(hal_soc_handle_t hal_soc_hdl,
250 hal_ring_handle_t hal_ring_hdl)
251 {
252 }
253
254 /* TX MONITOR */
255 #if defined(WLAN_PKT_CAPTURE_TX_2_0) && defined(TX_MONITOR_WORD_MASK)
256
257 #define TX_FES_SETUP_MASK 0x3
258 typedef struct tx_fes_setup_compact_5332 hal_tx_fes_setup_t;
259 struct tx_fes_setup_compact_5332 {
260 /* DWORD - 0 */
261 uint32_t schedule_id;
262 /* DWORD - 1 */
263 uint32_t reserved_1a : 7, // [0: 6]
264 transmit_start_reason : 3, // [7: 9]
265 reserved_1b : 13, // [10: 22]
266 number_of_users : 6, // [28: 23]
267 mu_type : 1, // [29]
268 reserved_1c : 2; // [30]
269 /* DWORD - 2 */
270 uint32_t reserved_2a : 4, // [0: 3]
271 ndp_frame : 2, // [4: 5]
272 txbf : 1, // [6]
273 reserved_2b : 3, // [7: 9]
274 static_bandwidth : 3, // [12: 10]
275 reserved_2c : 1, // [13]
276 transmission_contains_mu_rts : 1, // [14]
277 reserved_2d : 17; // [15: 31]
278 /* DWORD - 3 */
279 uint32_t reserved_3a : 15, // [0: 14]
280 mu_ndp : 1, // [15]
281 reserved_3b : 11, // [16: 26]
282 ndpa : 1, // [27]
283 reserved_3c : 4; // [28: 31]
284 };
285
286 #define TX_PEER_ENTRY_MASK 0x103
287 typedef struct tx_peer_entry_compact_5332 hal_tx_peer_entry_t;
288 struct tx_peer_entry_compact_5332 {
289 /* DWORD - 0 */
290 uint32_t mac_addr_a_31_0 : 32;
291 /* DWORD - 1 */
292 uint32_t mac_addr_a_47_32 : 16,
293 mac_addr_b_15_0 : 16;
294 /* DWORD - 2 */
295 uint32_t mac_addr_b_47_16 : 32;
296 /* DWORD - 3 */
297 uint32_t reserved_3 : 32;
298 /* DWORD - 16 */
299 uint32_t reserved_16 : 32;
300 /* DWORD - 17 */
301 uint32_t multi_link_addr_crypto_enable : 1,
302 reserved_17_a : 15,
303 sw_peer_id : 16;
304 };
305
306 #define TX_QUEUE_EXT_MASK 0x1
307 typedef struct tx_queue_ext_compact_5332 hal_tx_queue_ext_t;
308 struct tx_queue_ext_compact_5332 {
309 /* DWORD - 0 */
310 uint32_t frame_ctl : 16,
311 qos_ctl : 16;
312 /* DWORD - 1 */
313 uint32_t ampdu_flag : 1,
314 reserved_1 : 31;
315 };
316
317 #define TX_MSDU_START_MASK 0x1
318 typedef struct tx_msdu_start_compact_5332 hal_tx_msdu_start_t;
319 struct tx_msdu_start_compact_5332 {
320 /* DWORD - 0 */
321 uint32_t reserved_0 : 32;
322 /* DWORD - 1 */
323 uint32_t reserved_1 : 32;
324 };
325
326 #define TX_MPDU_START_MASK 0x3
327 typedef struct tx_mpdu_start_compact_5332 hal_tx_mpdu_start_t;
328 struct tx_mpdu_start_compact_5332 {
329 /* DWORD - 0 */
330 uint32_t mpdu_length : 14,
331 frame_not_from_tqm : 1,
332 vht_control_present : 1,
333 mpdu_header_length : 8,
334 retry_count : 7,
335 wds : 1;
336 /* DWORD - 1 */
337 uint32_t pn_31_0 : 32;
338 /* DWORD - 2 */
339 uint32_t pn_47_32 : 16,
340 mpdu_sequence_number : 12,
341 raw_already_encrypted : 1,
342 frame_type : 2,
343 txdma_dropped_mpdu_warning : 1;
344 /* DWORD - 3 */
345 uint32_t reserved_3 : 32;
346 };
347
348 typedef struct rxpcu_user_setup_compact_5332 hal_rxpcu_user_setup_t;
349 struct rxpcu_user_setup_compact_5332 {
350 };
351
352 #define TX_FES_STATUS_END_MASK 0x7
353 typedef struct tx_fes_status_end_compact_5332 hal_tx_fes_status_end_t;
354 struct tx_fes_status_end_compact_5332 {
355 /* DWORD - 0 */
356 uint32_t reserved_0 : 32;
357 /* DWORD - 1 */
358 struct {
359 uint16_t phytx_abort_reason : 8,
360 user_number : 6,
361 reserved_1a : 2;
362 } phytx_abort_request_info_details;
363 uint16_t reserved_1b : 12,
364 phytx_abort_request_info_valid : 1,
365 reserved_1c : 3;
366 /* DWORD - 2 */
367 uint32_t start_of_frame_timestamp_15_0 : 16,
368 start_of_frame_timestamp_31_16 : 16;
369 /* DWORD - 3 */
370 uint32_t end_of_frame_timestamp_15_0 : 16,
371 end_of_frame_timestamp_31_16 : 16;
372 /* DWORD - 4 */
373 uint32_t terminate_ranging_sequence : 1,
374 reserved_4a : 7,
375 timing_status : 2,
376 response_type : 5,
377 r2r_end_status_to_follow : 1,
378 transmit_delay : 16;
379 /* DWORD - 5 */
380 uint32_t reserved_5 : 32;
381 };
382
383 #define RESPONSE_END_STATUS_MASK 0xD
384 typedef struct response_end_status_compact_5332 hal_response_end_status_t;
385 struct response_end_status_compact_5332 {
386 /* DWORD - 0 */
387 uint32_t coex_bt_tx_while_wlan_tx : 1,
388 coex_wan_tx_while_wlan_tx : 1,
389 coex_wlan_tx_while_wlan_tx : 1,
390 global_data_underflow_warning : 1,
391 response_transmit_status : 4,
392 phytx_pkt_end_info_valid : 1,
393 phytx_abort_request_info_valid : 1,
394 generated_response : 3,
395 mba_user_count : 7,
396 mba_fake_bitmap_count : 7,
397 coex_based_tx_bw : 3,
398 trig_response_related : 1,
399 dpdtrain_done : 1;
400 /* DWORD - 1 */
401 uint32_t reserved_1 : 32;
402 /* DWORD - 4 */
403 uint32_t reserved_4 : 32;
404 /* DWORD - 5 */
405 uint32_t start_of_frame_timestamp_15_0 : 16,
406 start_of_frame_timestamp_31_16 : 16;
407 /* DWORD - 6 */
408 uint32_t end_of_frame_timestamp_15_0 : 16,
409 end_of_frame_timestamp_31_16 : 16;
410 /* DWORD - 7 */
411 uint32_t reserved_7 : 32;
412 };
413
414 #define TX_FES_STATUS_PROT_MASK 0x2
415 typedef struct tx_fes_status_prot_compact_5332 hal_tx_fes_status_prot_t;
416 struct tx_fes_status_prot_compact_5332 {
417 /* DWORD - 2 */
418 uint32_t start_of_frame_timestamp_15_0 : 16,
419 start_of_frame_timestamp_31_16 : 16;
420 /* DWROD - 3 */
421 uint32_t end_of_frame_timestamp_15_0 : 16,
422 end_of_frame_timestamp_31_16 : 16;
423 };
424
425 #define PCU_PPDU_SETUP_INIT_MASK 0x1E800000
426 typedef struct pcu_ppdu_setup_init_compact_5332 hal_pcu_ppdu_setup_t;
427 struct pcu_ppdu_setup_init_compact_5332 {
428 /* DWORD - 46 */
429 uint32_t reserved_46 : 32;
430 /* DWORD - 47 */
431 uint32_t r2r_group_id : 6,
432 r2r_response_frame_type : 4,
433 r2r_sta_partial_aid : 11,
434 use_address_fields_for_protection : 1,
435 r2r_set_required_response_time : 1,
436 reserved_47 : 9;
437 /* DWORD - 50 */
438 uint32_t reserved_50 : 32;
439 /* DWORD - 51 */
440 uint32_t protection_frame_ad1_31_0 : 32;
441 /* DWORD - 52 */
442 uint32_t protection_frame_ad1_47_32 : 16,
443 protection_frame_ad2_15_0 : 16;
444 /* DWORD - 53 */
445 uint32_t protection_frame_ad2_47_16 : 32;
446 /* DWORD - 54 */
447 uint32_t reserved_54 : 32;
448 /* DWORD - 55 */
449 uint32_t protection_frame_ad3_31_0 : 32;
450 /* DWORD - 56 */
451 uint32_t protection_frame_ad3_47_32 : 16,
452 protection_frame_ad4_15_0 : 16;
453 /* DWORD - 57 */
454 uint32_t protection_frame_ad4_47_16 : 32;
455 };
456
457 /**
458 * hal_txmon_get_word_mask_qca5332() - api to get word mask for tx monitor
459 * @wmask: pointer to hal_txmon_word_mask_config_t
460 *
461 * Return: void
462 */
463 static inline
hal_txmon_get_word_mask_qca5332(void * wmask)464 void hal_txmon_get_word_mask_qca5332(void *wmask)
465 {
466 hal_txmon_word_mask_config_t *word_mask = NULL;
467
468 word_mask = (hal_txmon_word_mask_config_t *)wmask;
469
470 word_mask->compaction_enable = 1;
471 word_mask->tx_fes_setup = TX_FES_SETUP_MASK;
472 word_mask->tx_peer_entry = TX_PEER_ENTRY_MASK;
473 word_mask->tx_queue_ext = TX_QUEUE_EXT_MASK;
474 word_mask->tx_msdu_start = TX_MSDU_START_MASK;
475 word_mask->pcu_ppdu_setup_init = PCU_PPDU_SETUP_INIT_MASK;
476 word_mask->tx_mpdu_start = TX_MPDU_START_MASK;
477 word_mask->rxpcu_user_setup = 0xFF;
478 word_mask->tx_fes_status_end = TX_FES_STATUS_END_MASK;
479 word_mask->response_end_status = RESPONSE_END_STATUS_MASK;
480 word_mask->tx_fes_status_prot = TX_FES_STATUS_PROT_MASK;
481 }
482 #endif /* WLAN_PKT_CAPTURE_TX_2_0 && TX_MONITOR_WORD_MASK */
483 #endif /* _HAL_5332_TX_H_ */
484