1 /*
2  * Copyright (c) 2016-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
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 #ifndef __DP_BE_TX_H
20 #define __DP_BE_TX_H
21 /**
22  *  DOC: dp_be_tx.h
23  *
24  * BE specific TX Datapath header file. Need not be exposed to common DP code.
25  *
26  */
27 
28 #include <dp_types.h>
29 #include "dp_be.h"
30 
31 struct __attribute__((__packed__)) dp_tx_comp_peer_id {
32 	uint16_t peer_id:13,
33 		 ml_peer_valid:1,
34 		 reserved:2;
35 };
36 
37 /* Invalid TX Bank ID value */
38 #define DP_BE_INVALID_BANK_ID -1
39 
40 /* Extraction of msdu queue information from per packet sawf metadata */
41 #define DP_TX_HLOS_TID_GET(_var) \
42 	(((_var) & 0x0e) >> 1)
43 #define DP_TX_FLOW_OVERRIDE_GET(_var) \
44 	((_var >> 3) & 0x1)
45 #define DP_TX_WHO_CLFY_INF_SEL_GET(_var) \
46 	(((_var) & 0x30) >> 4)
47 #define DP_TX_FLOW_OVERRIDE_ENABLE 0x1
48 
49 #define DP_TX_FAST_DESC_SIZE	28
50 #define DP_TX_L3_L4_CSUM_ENABLE	0x1f
51 
52 #ifdef DP_USE_REDUCED_PEER_ID_FIELD_WIDTH
53 static inline uint16_t
dp_tx_comp_adjust_peer_id_be(struct dp_soc * soc,uint16_t peer_id)54 dp_tx_comp_adjust_peer_id_be(struct dp_soc *soc, uint16_t peer_id)
55 {
56 	struct dp_tx_comp_peer_id *tx_peer_id =
57 		(struct dp_tx_comp_peer_id *)&peer_id;
58 
59 	return (tx_peer_id->peer_id |
60 		(tx_peer_id->ml_peer_valid << soc->peer_id_shift));
61 }
62 /**
63  * dp_tx_comp_get_peer_id_be() - Get peer ID from TX Comp Desc
64  * @soc: Handle to DP Soc structure
65  * @tx_comp_hal_desc: TX comp ring descriptor
66  *
67  * Return: Peer ID
68  */
dp_tx_comp_get_peer_id_be(struct dp_soc * soc,void * tx_comp_hal_desc)69 static inline uint16_t dp_tx_comp_get_peer_id_be(struct dp_soc *soc,
70 						 void *tx_comp_hal_desc)
71 {
72 	uint16_t peer_id = hal_tx_comp_get_peer_id(tx_comp_hal_desc);
73 
74 	return dp_tx_comp_adjust_peer_id_be(soc, peer_id);
75 }
76 #else
77 static inline uint16_t
dp_tx_comp_adjust_peer_id_be(struct dp_soc * soc,uint16_t peer_id)78 dp_tx_comp_adjust_peer_id_be(struct dp_soc *soc, uint16_t peer_id)
79 {
80 	return peer_id;
81 }
dp_tx_comp_get_peer_id_be(struct dp_soc * soc,void * tx_comp_hal_desc)82 static inline uint16_t dp_tx_comp_get_peer_id_be(struct dp_soc *soc,
83 						 void *tx_comp_hal_desc)
84 {
85 	return hal_tx_comp_get_peer_id(tx_comp_hal_desc);
86 
87 }
88 #endif
89 
90 /**
91  * dp_tx_hw_enqueue_be() - Enqueue to TCL HW for transmit for BE target
92  * @soc: DP Soc Handle
93  * @vdev: DP vdev handle
94  * @tx_desc: Tx Descriptor Handle
95  * @fw_metadata: Metadata to send to Target Firmware along with frame
96  * @metadata: Handle that holds exception path meta data
97  * @msdu_info: msdu_info containing information about TX buffer
98  *
99  *  Gets the next free TCL HW DMA descriptor and sets up required parameters
100  *  from software Tx descriptor
101  *
102  * Return: QDF_STATUS_SUCCESS: success
103  *         QDF_STATUS_E_RESOURCES: Error return
104  */
105 QDF_STATUS dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
106 			       struct dp_tx_desc_s *tx_desc,
107 				uint16_t fw_metadata,
108 				struct cdp_tx_exception_metadata *metadata,
109 				struct dp_tx_msdu_info_s *msdu_info);
110 
111 #ifdef QCA_DP_TX_NBUF_LIST_FREE
112 /**
113  * dp_tx_fast_send_be() - Transmit a frame on a given VAP
114  * @soc_hdl: DP soc handle
115  * @vdev_id: id of DP vdev handle
116  * @nbuf: skb
117  *
118  * Entry point for Core Tx layer (DP_TX) invoked from
119  * hard_start_xmit in OSIF/HDD or from dp_rx_process for intravap forwarding
120  * cases
121  *
122  * Return: NULL on success,
123  *         nbuf when it fails to send
124  */
125 qdf_nbuf_t dp_tx_fast_send_be(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
126 			      qdf_nbuf_t nbuf);
127 #else
dp_tx_fast_send_be(struct cdp_soc_t * soc,uint8_t vdev_id,qdf_nbuf_t nbuf)128 static inline qdf_nbuf_t dp_tx_fast_send_be(struct cdp_soc_t *soc, uint8_t vdev_id,
129 					    qdf_nbuf_t nbuf)
130 {
131 	return NULL;
132 }
133 #endif
134 
135 /**
136  * dp_tx_comp_get_params_from_hal_desc_be() - Get TX desc from HAL comp desc
137  * @soc: DP soc handle
138  * @tx_comp_hal_desc: HAL TX Comp Descriptor
139  * @r_tx_desc: SW Tx Descriptor retrieved from HAL desc.
140  *
141  * Return: QDF_STATUS
142  */
143 QDF_STATUS
144 dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc *soc,
145 				       void *tx_comp_hal_desc,
146 				       struct dp_tx_desc_s **r_tx_desc);
147 
148 /**
149  * dp_tx_process_htt_completion_be() - Tx HTT Completion Indication Handler
150  * @soc: Handle to DP soc structure
151  * @tx_desc: software descriptor head pointer
152  * @status: Tx completion status from HTT descriptor
153  * @ring_id: ring number
154  *
155  * This function will process HTT Tx indication messages from Target
156  *
157  * Return: none
158  */
159 void dp_tx_process_htt_completion_be(struct dp_soc *soc,
160 				     struct dp_tx_desc_s *tx_desc,
161 				     uint8_t *status,
162 				     uint8_t ring_id);
163 
164 /**
165  * dp_tx_init_bank_profiles() - Init TX bank profiles
166  * @soc: DP soc handle
167  *
168  * Return: QDF_STATUS_SUCCESS or QDF error code.
169  */
170 QDF_STATUS dp_tx_init_bank_profiles(struct dp_soc_be *soc);
171 
172 /**
173  * dp_tx_deinit_bank_profiles() - De-Init TX bank profiles
174  * @soc: DP soc handle
175  *
176  * Return: None
177  */
178 void dp_tx_deinit_bank_profiles(struct dp_soc_be *soc);
179 
180 /**
181  * dp_tx_get_bank_profile() - get TX bank profile for vdev
182  * @soc: DP soc handle
183  * @be_vdev: BE vdev pointer
184  *
185  * Return: bank profile allocated to vdev or DP_BE_INVALID_BANK_ID
186  */
187 int dp_tx_get_bank_profile(struct dp_soc_be *soc,
188 			   struct dp_vdev_be *be_vdev);
189 
190 /**
191  * dp_tx_put_bank_profile() - release TX bank profile for vdev
192  * @soc: DP soc handle
193  * @be_vdev: pointer to be_vdev structure
194  *
195  * Return: None
196  */
197 void dp_tx_put_bank_profile(struct dp_soc_be *soc, struct dp_vdev_be *be_vdev);
198 
199 /**
200  * dp_tx_update_bank_profile() - release existing and allocate new bank profile
201  * @be_soc: DP soc handle
202  * @be_vdev: pointer to be_vdev structure
203  *
204  * The function releases the existing bank profile allocated to the vdev and
205  * looks for a new bank profile based on updated dp_vdev TX params.
206  *
207  * Return: None
208  */
209 void dp_tx_update_bank_profile(struct dp_soc_be *be_soc,
210 			       struct dp_vdev_be *be_vdev);
211 
212 /**
213  * dp_tx_desc_pool_init_be() - Initialize Tx Descriptor pool(s)
214  * @soc: Handle to DP Soc structure
215  * @num_elem: number of descriptor in pool
216  * @pool_id: pool ID to allocate
217  * @spcl_tx_desc: if special desc
218  *
219  * Return: QDF_STATUS_SUCCESS - success, others - failure
220  */
221 QDF_STATUS dp_tx_desc_pool_init_be(struct dp_soc *soc,
222 				   uint32_t num_elem,
223 				   uint8_t pool_id,
224 				   bool spcl_tx_desc);
225 /**
226  * dp_tx_desc_pool_deinit_be() - De-initialize Tx Descriptor pool(s)
227  * @soc: Handle to DP Soc structure
228  * @tx_desc_pool: Tx descriptor pool handler
229  * @pool_id: pool ID to deinit
230  * @spcl_tx_desc: if special desc
231  *
232  * Return: None
233  */
234 void dp_tx_desc_pool_deinit_be(struct dp_soc *soc,
235 			       struct dp_tx_desc_pool_s *tx_desc_pool,
236 			       uint8_t pool_id, bool spcl_tx_desc);
237 
238 #ifdef WLAN_SUPPORT_PPEDS
239 /**
240  * dp_ppeds_tx_comp_handler()- Handle tx completions for ppe2tcl ring
241  * @be_soc: Handle to DP Soc structure
242  * @quota: Max number of tx completions to process
243  *
244  * Return: Number of tx completions processed
245  */
246 int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota);
247 
248 /*
249  * dp_ppeds_stats() - Accounting fw2wbm_tx_drop drops in Tx path
250  * @soc: Handle to DP Soc structure
251  * @peer_id: Peer ID in the descriptor
252  *
253  * Return: NONE
254  */
255 
256 static inline
257 void dp_ppeds_stats(struct dp_soc *soc, uint16_t peer_id);
258 
259 #endif
260 #ifdef WLAN_FEATURE_11BE_MLO
261 /**
262  * dp_tx_mlo_mcast_handler_be() - Tx handler for Mcast packets
263  * @soc: Handle to DP Soc structure
264  * @vdev: DP vdev handle
265  * @nbuf: nbuf to be enqueued
266  *
267  * Return: None
268  */
269 void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
270 				struct dp_vdev *vdev,
271 				qdf_nbuf_t nbuf);
272 
273 /**
274  * dp_tx_mlo_is_mcast_primary_be() - Function to check for primary mcast vdev
275  * @soc: Handle to DP Soc structure
276  * @vdev: DP vdev handle
277  *
278  * Return: True if vdev is mcast primary
279  *         False for all othercase
280  */
281 bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
282 				   struct dp_vdev *vdev);
283 #ifdef WLAN_MCAST_MLO
284 #ifdef WLAN_MLO_MULTI_CHIP
285 #ifdef CONFIG_MLO_SINGLE_DEV
286 /**
287  * dp_tx_mlo_mcast_send_be() - Tx send handler for mlo mcast enhance
288  * @soc: DP soc handle
289  * @vdev: DP vdev handle
290  * @nbuf: skb
291  * @tx_exc_metadata: Handle that holds exception path meta data
292  *
293  * Return: NULL for success
294  *         nbuf for failure
295  */
296 
297 qdf_nbuf_t dp_tx_mlo_mcast_send_be(struct dp_soc *soc, struct dp_vdev *vdev,
298 				   qdf_nbuf_t nbuf,
299 				   struct cdp_tx_exception_metadata
300 				   *tx_exc_metadata);
301 #endif
302 /**
303  * dp_tx_mlo_mcast_pkt_send() - handler to send MLO Mcast packets
304  * @be_vdev: Handle to DP be_vdev structure
305  * @ptnr_vdev: DP ptnr_vdev handle
306  * @arg: nbuf to be enqueued
307  *
308  * Return: None
309  */
310 void dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
311 			      struct dp_vdev *ptnr_vdev,
312 			      void *arg);
313 #endif
314 #endif
315 #endif
316 
317 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
318 /**
319  * dp_tx_comp_nf_handler() - Tx completion ring Near full scenario handler
320  * @int_ctx: Interrupt context
321  * @soc: Datapath SoC handle
322  * @hal_ring_hdl: TX completion ring handle
323  * @ring_id: TX completion ring number
324  * @quota: Quota of the work to be done
325  *
326  * Return: work done
327  */
328 uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
329 			       hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
330 			       uint32_t quota);
331 #else
332 static inline
dp_tx_comp_nf_handler(struct dp_intr * int_ctx,struct dp_soc * soc,hal_ring_handle_t hal_ring_hdl,uint8_t ring_id,uint32_t quota)333 uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
334 			       hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
335 			       uint32_t quota)
336 {
337 	return 0;
338 }
339 #endif /* WLAN_FEATURE_NEAR_FULL_IRQ */
340 
341 /**
342  * dp_tx_compute_tx_delay_be() - Compute HW Tx completion delay
343  * @soc: Handle to DP Soc structure
344  * @vdev: vdev
345  * @ts: Tx completion status
346  * @delay_us: Delay to be calculated in microseconds
347  *
348  * Return: QDF_STATUS
349  */
350 QDF_STATUS dp_tx_compute_tx_delay_be(struct dp_soc *soc,
351 				     struct dp_vdev *vdev,
352 				     struct hal_tx_completion_status *ts,
353 				     uint32_t *delay_us);
354 
355 /**
356  * dp_tx_desc_pool_alloc_be() - Allocate TX descriptor pool
357  * @soc: Handle to DP Soc structure
358  * @num_elem: Number of elements to allocate
359  * @pool_id: TCL descriptor pool ID
360  *
361  * Return: QDF_STATUS
362  */
363 QDF_STATUS dp_tx_desc_pool_alloc_be(struct dp_soc *soc, uint32_t num_elem,
364 				    uint8_t pool_id);
365 
366 /**
367  * dp_tx_desc_pool_free_be() - Free TX descriptor pool
368  * @soc: Handle to DP Soc structure
369  * @pool_id: TCL descriptor pool ID
370  *
371  * Return: none
372  */
373 void dp_tx_desc_pool_free_be(struct dp_soc *soc, uint8_t pool_id);
374 #endif
375