xref: /wlan-dirver/qca-wifi-host-cmn/hal/wifi3.0/qcn6122/hal_qcn6122_tx.h (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include "hal_hw_headers.h"
18 #include "hal_internal.h"
19 #include "cdp_txrx_mon_struct.h"
20 #include "qdf_trace.h"
21 #include "hal_rx.h"
22 #include "hal_tx.h"
23 #include "dp_types.h"
24 #include "hal_api_mon.h"
25 
26 /**
27  * hal_tx_desc_set_dscp_tid_table_id_6122() - Sets DSCP to TID conversion
28  *						table ID
29  * @desc: Handle to Tx Descriptor
30  * @id: DSCP to tid conversion table to be used for this frame
31  *
32  * Return: void
33  */
34 static void hal_tx_desc_set_dscp_tid_table_id_6122(void *desc, uint8_t id)
35 {
36 	HAL_SET_FLD(desc, TCL_DATA_CMD_5,
37 		    DSCP_TID_TABLE_NUM) |=
38 		    HAL_TX_SM(TCL_DATA_CMD_5, DSCP_TID_TABLE_NUM, id);
39 }
40 
41 #define DSCP_TID_TABLE_SIZE 24
42 #define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4)
43 #define HAL_TX_NUM_DSCP_REGISTER_SIZE 32
44 
45 /**
46  * hal_tx_set_dscp_tid_map_6122() - Configure default DSCP to TID map table
47  * @soc: HAL SoC context
48  * @map: DSCP-TID mapping table
49  * @id: mapping table ID - 0,1
50  *
51  * DSCP are mapped to 8 TID values using TID values programmed
52  * in two set of mapping registers DSCP_TID1_MAP_<0 to 6> (id = 0)
53  * and DSCP_TID2_MAP_<0 to 6> (id = 1)
54  * Each mapping register has TID mapping for 10 DSCP values
55  *
56  * Return: none
57  */
58 static void hal_tx_set_dscp_tid_map_6122(struct hal_soc *soc,
59 					 uint8_t *map, uint8_t id)
60 {
61 	int i;
62 	uint32_t addr, cmn_reg_addr;
63 	uint32_t value = 0, regval;
64 	uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0;
65 
66 	if (id >= HAL_MAX_HW_DSCP_TID_MAPS_11AX)
67 		return;
68 
69 	cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(
70 					SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET);
71 
72 	addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR(
73 				SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET,
74 				id * NUM_WORDS_PER_DSCP_TID_TABLE);
75 
76 	/* Enable read/write access */
77 	regval = HAL_REG_READ(soc, cmn_reg_addr);
78 	regval |=
79 	(1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT);
80 
81 	HAL_REG_WRITE(soc, cmn_reg_addr, regval);
82 
83 	/* Write 8 (24 bits) DSCP-TID mappings in each interation */
84 	for (i = 0; i < 64; i += 8) {
85 		value = (map[i] |
86 			(map[i + 1] << 0x3) |
87 			(map[i + 2] << 0x6) |
88 			(map[i + 3] << 0x9) |
89 			(map[i + 4] << 0xc) |
90 			(map[i + 5] << 0xf) |
91 			(map[i + 6] << 0x12) |
92 			(map[i + 7] << 0x15));
93 
94 		qdf_mem_copy(&val[cnt], &value, 3);
95 		cnt += 3;
96 	}
97 
98 	for (i = 0; i < DSCP_TID_TABLE_SIZE; i += 4) {
99 		regval = *(uint32_t *)(val + i);
100 		HAL_REG_WRITE(soc, addr,
101 			      (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK));
102 		addr += 4;
103 	}
104 
105 	/* Diasble read/write access */
106 	regval = HAL_REG_READ(soc, cmn_reg_addr);
107 	regval &=
108 	~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK);
109 
110 	HAL_REG_WRITE(soc, cmn_reg_addr, regval);
111 }
112 
113 /**
114  * hal_tx_update_dscp_tid_6122() - Update the dscp tid map table as
115 					updated by user
116  * @soc: HAL SoC context
117  * @map: DSCP-TID mapping table
118  * @id : MAP ID
119  * @dscp: DSCP_TID map index
120  *
121  * Return: void
122  */
123 static void hal_tx_update_dscp_tid_6122(struct hal_soc *soc, uint8_t tid,
124 					uint8_t id, uint8_t dscp)
125 {
126 	uint32_t addr, addr1, cmn_reg_addr;
127 	uint32_t start_value = 0, end_value = 0;
128 	uint32_t regval;
129 	uint8_t end_bits = 0;
130 	uint8_t start_bits = 0;
131 	uint32_t start_index, end_index;
132 
133 	cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR(
134 					SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET);
135 
136 	addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR(
137 				SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET,
138 				id * NUM_WORDS_PER_DSCP_TID_TABLE);
139 
140 	start_index = dscp * HAL_TX_BITS_PER_TID;
141 	end_index = (start_index + (HAL_TX_BITS_PER_TID - 1))
142 		    % HAL_TX_NUM_DSCP_REGISTER_SIZE;
143 	start_index = start_index % HAL_TX_NUM_DSCP_REGISTER_SIZE;
144 	addr += (4 * ((dscp * HAL_TX_BITS_PER_TID) /
145 			HAL_TX_NUM_DSCP_REGISTER_SIZE));
146 
147 	if (end_index < start_index) {
148 		end_bits = end_index + 1;
149 		start_bits = HAL_TX_BITS_PER_TID - end_bits;
150 		start_value = tid << start_index;
151 		end_value = tid >> start_bits;
152 		addr1 = addr + 4;
153 	} else {
154 		start_bits = HAL_TX_BITS_PER_TID - end_bits;
155 		start_value = tid << start_index;
156 		addr1 = 0;
157 	}
158 
159 	/* Enable read/write access */
160 	regval = HAL_REG_READ(soc, cmn_reg_addr);
161 	regval |=
162 	(1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT);
163 
164 	HAL_REG_WRITE(soc, cmn_reg_addr, regval);
165 
166 	regval = HAL_REG_READ(soc, addr);
167 
168 	if (end_index < start_index)
169 		regval &= (~0) >> start_bits;
170 	else
171 		regval &= ~(7 << start_index);
172 
173 	regval |= start_value;
174 
175 	HAL_REG_WRITE(soc, addr, (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK));
176 
177 	if (addr1) {
178 		regval = HAL_REG_READ(soc, addr1);
179 		regval &= (~0) << end_bits;
180 		regval |= end_value;
181 
182 		HAL_REG_WRITE(soc, addr1, (regval &
183 			     HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK));
184 	}
185 
186 	/* Diasble read/write access */
187 	regval = HAL_REG_READ(soc, cmn_reg_addr);
188 	regval &=
189 	~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK);
190 	HAL_REG_WRITE(soc, cmn_reg_addr, regval);
191 }
192 
193 /**
194  * hal_tx_desc_set_lmac_id_6122 - Set the lmac_id value
195  * @desc: Handle to Tx Descriptor
196  * @lmac_id: mac Id to ast matching
197  *		     b00 – mac 0
198  *		     b01 – mac 1
199  *		     b10 – mac 2
200  *		     b11 – all macs (legacy HK way)
201  *
202  * Return: void
203  */
204 static void hal_tx_desc_set_lmac_id_6122(void *desc, uint8_t lmac_id)
205 {
206 	HAL_SET_FLD(desc, TCL_DATA_CMD_4, LMAC_ID) |=
207 		HAL_TX_SM(TCL_DATA_CMD_4, LMAC_ID, lmac_id);
208 }
209 
210 /**
211  * hal_tx_init_cmd_credit_ring_6122() - Initialize TCL command/credit SRNG
212  * @hal_soc_hdl: Handle to HAL SoC structure
213  * @hal_srng: Handle to HAL SRNG structure
214  *
215  * Return: none
216  */
217 static inline void
218 hal_tx_init_cmd_credit_ring_6122(hal_soc_handle_t hal_soc_hdl,
219 				 hal_ring_handle_t hal_ring_hdl)
220 {
221 	uint8_t *desc_addr;
222 	struct hal_srng_params srng_params;
223 	uint32_t desc_size;
224 	uint32_t num_desc;
225 
226 	hal_get_srng_params(hal_soc_hdl, hal_ring_hdl, &srng_params);
227 
228 	desc_addr = (uint8_t *)srng_params.ring_base_vaddr;
229 	desc_size = sizeof(struct tcl_data_cmd);
230 	num_desc = srng_params.num_entries;
231 
232 	while (num_desc) {
233 		/* using CMD/CREDIT Ring to send DATA CMD tag */
234 		HAL_TX_DESC_SET_TLV_HDR(desc_addr, WIFITCL_DATA_CMD_E,
235 					desc_size);
236 		desc_addr += (desc_size + sizeof(struct tlv_32_hdr));
237 		num_desc--;
238 	}
239 }
240