xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/qca5332/hal_5332_tx.h (revision d0c05845839e5f2ba5a8dcebe0cd3e4cd4e8dfcf)
1 /*
2  * Copyright (c) 2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022, 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  * @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  */
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)
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 interation */
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 	/* Diasble 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  * @map: DSCP-TID mapping table
107  * @id : MAP ID
108  * @dscp: DSCP_TID map index
109  *
110  * Return: void
111  */
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 	/* Diasble 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() - Update return buffer manager ring id
192  * @hal_soc: 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
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
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_srng: Handle to HAL SRNG structure
245  *
246  * Return: none
247  */
248 static inline void
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 #ifdef QCA_MONITOR_2_0_SUPPORT
256 
257 #if defined(TX_MONITOR_WORD_MASK)
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 #endif
286 #endif /* QCA_MONITOR_2_0_SUPPORT */
287 #endif /* _HAL_5332_TX_H_ */
288