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