xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/be/dp_be_tx.c (revision 5113495b16420b49004c444715d2daae2066e7dc) !
1 /*
2  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 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 
20 #include "cdp_txrx_cmn_struct.h"
21 #include "dp_types.h"
22 #include "dp_tx.h"
23 #include "dp_be_tx.h"
24 #include "dp_tx_desc.h"
25 #include "hal_tx.h"
26 #include <hal_be_api.h>
27 #include <hal_be_tx.h>
28 #include <dp_htt.h>
29 #include "dp_internal.h"
30 #ifdef FEATURE_WDS
31 #include "dp_txrx_wds.h"
32 #endif
33 
34 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1)
35 #define DP_TX_BANK_LOCK_CREATE(lock) qdf_mutex_create(lock)
36 #define DP_TX_BANK_LOCK_DESTROY(lock) qdf_mutex_destroy(lock)
37 #define DP_TX_BANK_LOCK_ACQUIRE(lock) qdf_mutex_acquire(lock)
38 #define DP_TX_BANK_LOCK_RELEASE(lock) qdf_mutex_release(lock)
39 #else
40 #define DP_TX_BANK_LOCK_CREATE(lock) qdf_spinlock_create(lock)
41 #define DP_TX_BANK_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock)
42 #define DP_TX_BANK_LOCK_ACQUIRE(lock) qdf_spin_lock_bh(lock)
43 #define DP_TX_BANK_LOCK_RELEASE(lock) qdf_spin_unlock_bh(lock)
44 #endif
45 
46 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
47 #ifdef WLAN_MCAST_MLO
48 /* MLO peer id for reinject*/
49 #define DP_MLO_MCAST_REINJECT_PEER_ID 0XFFFD
50 #define MAX_GSN_NUM 0x0FFF
51 
52 #ifdef QCA_MULTIPASS_SUPPORT
53 #define INVALID_VLAN_ID         0xFFFF
54 #define MULTIPASS_WITH_VLAN_ID 0xFFFE
55 /**
56  * struct dp_mlo_mpass_buf - Multipass buffer
57  * @vlan_id: vlan_id of frame
58  * @nbuf: pointer to skb buf
59  */
60 struct dp_mlo_mpass_buf {
61 	uint16_t vlan_id;
62 	qdf_nbuf_t  nbuf;
63 };
64 #endif
65 #endif
66 #endif
67 
68 #define DP_TX_WBM_COMPLETION_V3_VDEV_ID_GET(_var) \
69 	HTT_TX_WBM_COMPLETION_V2_VDEV_ID_GET(_var)
70 #define DP_TX_WBM_COMPLETION_V3_VALID_GET(_var) \
71 	HTT_TX_WBM_COMPLETION_V2_VALID_GET(_var)
72 #define DP_TX_WBM_COMPLETION_V3_SW_PEER_ID_GET(_var) \
73 	HTT_TX_WBM_COMPLETION_V2_SW_PEER_ID_GET(_var)
74 #define DP_TX_WBM_COMPLETION_V3_TID_NUM_GET(_var) \
75 	HTT_TX_WBM_COMPLETION_V2_TID_NUM_GET(_var)
76 #define DP_TX_WBM_COMPLETION_V3_SCH_CMD_ID_GET(_var) \
77 	HTT_TX_WBM_COMPLETION_V2_SCH_CMD_ID_GET(_var)
78 #define DP_TX_WBM_COMPLETION_V3_ACK_FRAME_RSSI_GET(_var) \
79 	HTT_TX_WBM_COMPLETION_V2_ACK_FRAME_RSSI_GET(_var)
80 #define DP_TX_WBM_COMPLETION_V3_TRANSMIT_CNT_VALID_GET(_var) \
81 	HTT_TX_WBM_COMPLETION_V2_TRANSMIT_CNT_VALID_GET(_var)
82 
83 extern uint8_t sec_type_map[MAX_CDP_SEC_TYPE];
84 
85 #ifdef DP_TX_COMP_RING_DESC_SANITY_CHECK
86 /*
87  * Value to mark ring desc is invalidated by buffer_virt_addr_63_32 field
88  * of WBM2SW ring Desc.
89  */
90 #define DP_TX_COMP_DESC_BUFF_VA_32BITS_HI_INVALIDATE 0x12121212
91 
92 /**
93  * dp_tx_comp_desc_check_and_invalidate() - sanity check for ring desc and
94  *					    invalidate it after each reaping
95  * @tx_comp_hal_desc: ring desc virtual address
96  * @r_tx_desc: pointer to current dp TX Desc pointer
97  * @tx_desc_va: the original 64 bits Desc VA got from ring Desc
98  * @hw_cc_done: HW cookie conversion done or not
99  *
100  * If HW CC is done, check the buffer_virt_addr_63_32 value to know if
101  * ring Desc is stale or not. if HW CC is not done, then compare PA between
102  * ring Desc and current TX desc.
103  *
104  * Return: QDF_STATUS_SUCCESS for success,
105  *	   QDF_STATUS_E_PENDING for stale entry,
106  *	   QDF_STATUS_E_INVAL for invalid entry.
107  */
108 static inline
dp_tx_comp_desc_check_and_invalidate(void * tx_comp_hal_desc,struct dp_tx_desc_s ** r_tx_desc,uint64_t tx_desc_va,bool hw_cc_done)109 QDF_STATUS dp_tx_comp_desc_check_and_invalidate(void *tx_comp_hal_desc,
110 						struct dp_tx_desc_s **r_tx_desc,
111 						uint64_t tx_desc_va,
112 						bool hw_cc_done)
113 {
114 	qdf_dma_addr_t desc_dma_addr;
115 	QDF_STATUS status = QDF_STATUS_SUCCESS;
116 
117 	if (qdf_likely(hw_cc_done)) {
118 		/* Check upper 32 bits */
119 		if (DP_TX_COMP_DESC_BUFF_VA_32BITS_HI_INVALIDATE ==
120 		    (tx_desc_va >> 32)) {
121 			*r_tx_desc = NULL;
122 			status = QDF_STATUS_E_PENDING;
123 		} else
124 			/* Invalidate the ring desc for 32 ~ 63 bits of VA */
125 			hal_tx_comp_set_desc_va_63_32(
126 				tx_comp_hal_desc,
127 				DP_TX_COMP_DESC_BUFF_VA_32BITS_HI_INVALIDATE);
128 	} else {
129 		/* Compare PA between ring desc and current TX desc stored */
130 		desc_dma_addr = hal_tx_comp_get_paddr(tx_comp_hal_desc);
131 
132 		if (desc_dma_addr != (*r_tx_desc)->dma_addr) {
133 			*r_tx_desc = NULL;
134 			status = QDF_STATUS_E_INVAL;
135 		}
136 	}
137 
138 	return status;
139 }
140 #else
141 static inline
dp_tx_comp_desc_check_and_invalidate(void * tx_comp_hal_desc,struct dp_tx_desc_s ** r_tx_desc,uint64_t tx_desc_va,bool hw_cc_done)142 QDF_STATUS dp_tx_comp_desc_check_and_invalidate(void *tx_comp_hal_desc,
143 						struct dp_tx_desc_s **r_tx_desc,
144 						uint64_t tx_desc_va,
145 						bool hw_cc_done)
146 {
147 	return QDF_STATUS_SUCCESS;
148 }
149 #endif
150 
151 #ifdef DP_FEATURE_HW_COOKIE_CONVERSION
152 #ifdef DP_HW_COOKIE_CONVERT_EXCEPTION
153 QDF_STATUS
dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc * soc,void * tx_comp_hal_desc,struct dp_tx_desc_s ** r_tx_desc)154 dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc *soc,
155 				       void *tx_comp_hal_desc,
156 				       struct dp_tx_desc_s **r_tx_desc)
157 {
158 	uint32_t tx_desc_id;
159 	uint64_t tx_desc_va = 0;
160 	QDF_STATUS status;
161 	bool hw_cc_done =
162 		hal_tx_comp_get_cookie_convert_done(tx_comp_hal_desc);
163 
164 	if (qdf_likely(hw_cc_done)) {
165 		/* HW cookie conversion done */
166 		tx_desc_va = hal_tx_comp_get_desc_va(tx_comp_hal_desc);
167 		*r_tx_desc = (struct dp_tx_desc_s *)(uintptr_t)tx_desc_va;
168 
169 	} else {
170 		/* SW do cookie conversion to VA */
171 		tx_desc_id = hal_tx_comp_get_desc_id(tx_comp_hal_desc);
172 		*r_tx_desc =
173 		(struct dp_tx_desc_s *)dp_cc_desc_find(soc, tx_desc_id);
174 	}
175 
176 	status = dp_tx_comp_desc_check_and_invalidate(tx_comp_hal_desc,
177 						      r_tx_desc, tx_desc_va,
178 						      hw_cc_done);
179 
180 	if (*r_tx_desc)
181 		(*r_tx_desc)->peer_id =
182 				dp_tx_comp_get_peer_id_be(soc,
183 							  tx_comp_hal_desc);
184 
185 	return status;
186 }
187 #else
188 QDF_STATUS
dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc * soc,void * tx_comp_hal_desc,struct dp_tx_desc_s ** r_tx_desc)189 dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc *soc,
190 				       void *tx_comp_hal_desc,
191 				       struct dp_tx_desc_s **r_tx_desc)
192 {
193 	uint64_t tx_desc_va;
194 	QDF_STATUS status;
195 
196 	tx_desc_va = hal_tx_comp_get_desc_va(tx_comp_hal_desc);
197 	*r_tx_desc = (struct dp_tx_desc_s *)(uintptr_t)tx_desc_va;
198 
199 	status = dp_tx_comp_desc_check_and_invalidate(tx_comp_hal_desc,
200 						      r_tx_desc, tx_desc_va,
201 						      true);
202 	if (*r_tx_desc)
203 		(*r_tx_desc)->peer_id =
204 				dp_tx_comp_get_peer_id_be(soc,
205 							  tx_comp_hal_desc);
206 
207 	return status;
208 }
209 #endif /* DP_HW_COOKIE_CONVERT_EXCEPTION */
210 #else
211 
212 QDF_STATUS
dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc * soc,void * tx_comp_hal_desc,struct dp_tx_desc_s ** r_tx_desc)213 dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc *soc,
214 				       void *tx_comp_hal_desc,
215 				       struct dp_tx_desc_s **r_tx_desc)
216 {
217 	uint32_t tx_desc_id;
218 	QDF_STATUS status;
219 
220 	/* SW do cookie conversion to VA */
221 	tx_desc_id = hal_tx_comp_get_desc_id(tx_comp_hal_desc);
222 	*r_tx_desc =
223 	(struct dp_tx_desc_s *)dp_cc_desc_find(soc, tx_desc_id);
224 
225 	status = dp_tx_comp_desc_check_and_invalidate(tx_comp_hal_desc,
226 						      r_tx_desc, 0, false);
227 
228 	if (*r_tx_desc)
229 		(*r_tx_desc)->peer_id =
230 				dp_tx_comp_get_peer_id_be(soc,
231 							  tx_comp_hal_desc);
232 
233 	return status;
234 }
235 #endif /* DP_FEATURE_HW_COOKIE_CONVERSION */
236 
237 static inline
dp_tx_process_mec_notify_be(struct dp_soc * soc,uint8_t * status)238 void dp_tx_process_mec_notify_be(struct dp_soc *soc, uint8_t *status)
239 {
240 	struct dp_vdev *vdev;
241 	uint8_t vdev_id;
242 	uint32_t *htt_desc = (uint32_t *)status;
243 
244 	dp_assert_always_internal(soc->mec_fw_offload);
245 
246 	/*
247 	 * Get vdev id from HTT status word in case of MEC
248 	 * notification
249 	 */
250 	vdev_id = DP_TX_WBM_COMPLETION_V3_VDEV_ID_GET(htt_desc[4]);
251 	if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
252 		return;
253 
254 	vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
255 				     DP_MOD_ID_HTT_COMP);
256 	if (!vdev)
257 		return;
258 	dp_tx_mec_handler(vdev, status);
259 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP);
260 }
261 
dp_tx_process_htt_completion_be(struct dp_soc * soc,struct dp_tx_desc_s * tx_desc,uint8_t * status,uint8_t ring_id)262 void dp_tx_process_htt_completion_be(struct dp_soc *soc,
263 				     struct dp_tx_desc_s *tx_desc,
264 				     uint8_t *status,
265 				     uint8_t ring_id)
266 {
267 	uint8_t tx_status;
268 	struct dp_pdev *pdev;
269 	struct dp_vdev *vdev = NULL;
270 	struct hal_tx_completion_status ts = {0};
271 	uint32_t *htt_desc = (uint32_t *)status;
272 	struct dp_txrx_peer *txrx_peer;
273 	dp_txrx_ref_handle txrx_ref_handle = NULL;
274 	struct cdp_tid_tx_stats *tid_stats = NULL;
275 	struct htt_soc *htt_handle;
276 	uint8_t vdev_id;
277 	uint16_t peer_id;
278 	uint8_t xmit_type;
279 
280 	tx_status = HTT_TX_WBM_COMPLETION_V3_TX_STATUS_GET(htt_desc[0]);
281 	htt_handle = (struct htt_soc *)soc->htt_handle;
282 	htt_wbm_event_record(htt_handle->htt_logger_handle, tx_status, status);
283 
284 	/*
285 	 * There can be scenario where WBM consuming descriptor enqueued
286 	 * from TQM2WBM first and TQM completion can happen before MEC
287 	 * notification comes from FW2WBM. Avoid access any field of tx
288 	 * descriptor in case of MEC notify.
289 	 */
290 	if (tx_status == HTT_TX_FW2WBM_TX_STATUS_MEC_NOTIFY)
291 		return dp_tx_process_mec_notify_be(soc, status);
292 
293 	/*
294 	 * If the descriptor is already freed in vdev_detach,
295 	 * continue to next descriptor
296 	 */
297 	if (qdf_unlikely(!tx_desc->flags)) {
298 		dp_tx_comp_info_rl("Descriptor freed in vdev_detach %d",
299 				   tx_desc->id);
300 		return;
301 	}
302 
303 	if (qdf_unlikely(tx_desc->vdev_id == DP_INVALID_VDEV_ID)) {
304 		dp_tx_comp_info_rl("Invalid vdev_id %d", tx_desc->id);
305 		tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
306 		goto release_tx_desc;
307 	}
308 
309 	pdev = tx_desc->pdev;
310 	if (qdf_unlikely(!pdev)) {
311 		dp_tx_comp_warn("The pdev in TX desc is NULL, dropped.");
312 		dp_tx_comp_warn("tx_status: %u", tx_status);
313 		tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
314 		goto release_tx_desc;
315 	}
316 
317 	if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
318 		dp_tx_comp_info_rl("pdev in down state %d", tx_desc->id);
319 		tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
320 		goto release_tx_desc;
321 	}
322 
323 	qdf_assert(tx_desc->pdev);
324 
325 	vdev_id = tx_desc->vdev_id;
326 	vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
327 				     DP_MOD_ID_HTT_COMP);
328 
329 	if (qdf_unlikely(!vdev)) {
330 		dp_tx_comp_info_rl("Unable to get vdev ref  %d", tx_desc->id);
331 		tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
332 		goto release_tx_desc;
333 	}
334 
335 	switch (tx_status) {
336 	case HTT_TX_FW2WBM_TX_STATUS_OK:
337 	case HTT_TX_FW2WBM_TX_STATUS_DROP:
338 	case HTT_TX_FW2WBM_TX_STATUS_TTL:
339 	{
340 		uint8_t tid;
341 		uint8_t transmit_cnt_valid = 0;
342 
343 		if (DP_TX_WBM_COMPLETION_V3_VALID_GET(htt_desc[3])) {
344 			ts.peer_id =
345 				DP_TX_WBM_COMPLETION_V3_SW_PEER_ID_GET(
346 						htt_desc[3]);
347 			ts.tid =
348 				DP_TX_WBM_COMPLETION_V3_TID_NUM_GET(
349 						htt_desc[3]);
350 		} else {
351 			ts.peer_id = HTT_INVALID_PEER;
352 			ts.tid = HTT_INVALID_TID;
353 		}
354 		ts.release_src = HAL_TX_COMP_RELEASE_SOURCE_FW;
355 		ts.ppdu_id =
356 			DP_TX_WBM_COMPLETION_V3_SCH_CMD_ID_GET(
357 					htt_desc[2]);
358 		ts.ack_frame_rssi =
359 			DP_TX_WBM_COMPLETION_V3_ACK_FRAME_RSSI_GET(
360 					htt_desc[2]);
361 
362 		transmit_cnt_valid =
363 			DP_TX_WBM_COMPLETION_V3_TRANSMIT_CNT_VALID_GET(
364 					htt_desc[3]);
365 		if (transmit_cnt_valid)
366 			ts.transmit_cnt =
367 				HTT_TX_WBM_COMPLETION_V3_TRANSMIT_COUNT_GET(
368 						htt_desc[1]);
369 
370 		ts.tsf = htt_desc[4];
371 		ts.first_msdu = 1;
372 		ts.last_msdu = 1;
373 		switch (tx_status) {
374 		case HTT_TX_FW2WBM_TX_STATUS_OK:
375 			ts.status = HAL_TX_TQM_RR_FRAME_ACKED;
376 			break;
377 		case HTT_TX_FW2WBM_TX_STATUS_DROP:
378 			ts.status = HAL_TX_TQM_RR_REM_CMD_REM;
379 			break;
380 		case HTT_TX_FW2WBM_TX_STATUS_TTL:
381 			ts.status = HAL_TX_TQM_RR_REM_CMD_TX;
382 			break;
383 		}
384 		tid = ts.tid;
385 		if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS))
386 			tid = CDP_MAX_DATA_TIDS - 1;
387 
388 		tid_stats = &pdev->stats.tid_stats.tid_tx_stats[ring_id][tid];
389 
390 		if (qdf_unlikely(pdev->delay_stats_flag) ||
391 		    qdf_unlikely(dp_is_vdev_tx_delay_stats_enabled(vdev)))
392 			dp_tx_compute_delay(vdev, tx_desc, tid, ring_id);
393 		if (tx_status < CDP_MAX_TX_HTT_STATUS)
394 			tid_stats->htt_status_cnt[tx_status]++;
395 
396 		peer_id = dp_tx_comp_adjust_peer_id_be(soc, ts.peer_id);
397 		txrx_peer = dp_txrx_peer_get_ref_by_id(soc, peer_id,
398 						       &txrx_ref_handle,
399 						       DP_MOD_ID_HTT_COMP);
400 		if (qdf_likely(txrx_peer))
401 			dp_tx_update_peer_basic_stats(
402 						txrx_peer,
403 						qdf_nbuf_len(tx_desc->nbuf),
404 						tx_status,
405 						pdev->enhanced_stats_en);
406 
407 		dp_tx_comp_process_tx_status(soc, tx_desc, &ts, txrx_peer,
408 					     ring_id);
409 		dp_tx_comp_process_desc(soc, tx_desc, &ts, txrx_peer);
410 		dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id);
411 
412 		if (qdf_likely(txrx_peer))
413 			dp_txrx_peer_unref_delete(txrx_ref_handle,
414 						  DP_MOD_ID_HTT_COMP);
415 
416 		break;
417 	}
418 	case HTT_TX_FW2WBM_TX_STATUS_REINJECT:
419 	{
420 		uint8_t reinject_reason;
421 
422 		reinject_reason =
423 			HTT_TX_WBM_COMPLETION_V3_REINJECT_REASON_GET(
424 								htt_desc[1]);
425 		dp_tx_reinject_handler(soc, vdev, tx_desc,
426 				       status, reinject_reason);
427 		break;
428 	}
429 	case HTT_TX_FW2WBM_TX_STATUS_INSPECT:
430 	{
431 		dp_tx_inspect_handler(soc, vdev, tx_desc, status);
432 		break;
433 	}
434 	case HTT_TX_FW2WBM_TX_STATUS_VDEVID_MISMATCH:
435 	{
436 		xmit_type = qdf_nbuf_get_vdev_xmit_type(tx_desc->nbuf);
437 		DP_STATS_INC(vdev,
438 			     tx_i[xmit_type].dropped.fail_per_pkt_vdev_id_check,
439 			     1);
440 		goto release_tx_desc;
441 	}
442 	default:
443 		dp_tx_comp_err("Invalid HTT tx_status %d\n",
444 			       tx_status);
445 		goto release_tx_desc;
446 	}
447 
448 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP);
449 	return;
450 
451 release_tx_desc:
452 	dp_tx_comp_free_buf(soc, tx_desc, false);
453 	dp_tx_desc_release(soc, tx_desc, tx_desc->pool_id);
454 	if (vdev)
455 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_HTT_COMP);
456 }
457 
458 #ifdef QCA_OL_TX_MULTIQ_SUPPORT
459 #ifdef DP_TX_IMPLICIT_RBM_MAPPING
460 /**
461  * dp_tx_get_rbm_id_be() - Get the RBM ID for data transmission completion.
462  * @soc: DP soc structure pointer
463  * @ring_id: Transmit Queue/ring_id to be used when XPS is enabled
464  *
465  * Return: RBM ID corresponding to TCL ring_id
466  */
dp_tx_get_rbm_id_be(struct dp_soc * soc,uint8_t ring_id)467 static inline uint8_t dp_tx_get_rbm_id_be(struct dp_soc *soc,
468 					  uint8_t ring_id)
469 {
470 	return 0;
471 }
472 #else
dp_tx_get_rbm_id_be(struct dp_soc * soc,uint8_t ring_id)473 static inline uint8_t dp_tx_get_rbm_id_be(struct dp_soc *soc,
474 					  uint8_t ring_id)
475 {
476 	return (ring_id ? soc->wbm_sw0_bm_id + (ring_id - 1) :
477 			  HAL_WBM_SW2_BM_ID(soc->wbm_sw0_bm_id));
478 }
479 #endif /*DP_TX_IMPLICIT_RBM_MAPPING*/
480 #else
dp_tx_get_rbm_id_be(struct dp_soc * soc,uint8_t tcl_index)481 static inline uint8_t dp_tx_get_rbm_id_be(struct dp_soc *soc,
482 					  uint8_t tcl_index)
483 {
484 	uint8_t rbm;
485 
486 	rbm = wlan_cfg_get_rbm_id_for_index(soc->wlan_cfg_ctx, tcl_index);
487 	dp_verbose_debug("tcl_id %u rbm %u", tcl_index, rbm);
488 	return rbm;
489 }
490 #endif
491 
492 #ifdef QCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES
493 
494 /**
495  * dp_tx_set_min_rates_for_critical_frames()- sets min-rates for critical pkts
496  * @soc: DP soc structure pointer
497  * @hal_tx_desc: HAL descriptor where fields are set
498  * @nbuf: skb to be considered for min rates
499  *
500  * The function relies on upper layers to set QDF_NBUF_CB_TX_EXTRA_IS_CRITICAL
501  * and uses it to determine if the frame is critical. For a critical frame,
502  * flow override bits are set to classify the frame into HW's high priority
503  * queue. The HW will pick pre-configured min rates for such packets.
504  *
505  * Return: None
506  */
507 static void
dp_tx_set_min_rates_for_critical_frames(struct dp_soc * soc,uint32_t * hal_tx_desc,qdf_nbuf_t nbuf)508 dp_tx_set_min_rates_for_critical_frames(struct dp_soc *soc,
509 					uint32_t *hal_tx_desc,
510 					qdf_nbuf_t nbuf)
511 {
512 /*
513  * Critical frames should be queued to the high priority queue for the TID on
514  * on which they are sent out (for the concerned peer).
515  * FW is using HTT_MSDU_Q_IDX 2 for HOL (high priority) queue.
516  * htt_msdu_idx = (2 * who_classify_info_sel) + flow_override
517  * Hence, using who_classify_info_sel = 1, flow_override = 0 to select
518  * HOL queue.
519  */
520 	if (QDF_NBUF_CB_TX_EXTRA_IS_CRITICAL(nbuf)) {
521 		hal_tx_desc_set_flow_override_enable(hal_tx_desc, 1);
522 		hal_tx_desc_set_flow_override(hal_tx_desc, 0);
523 		hal_tx_desc_set_who_classify_info_sel(hal_tx_desc, 1);
524 		hal_tx_desc_set_tx_notify_frame(hal_tx_desc,
525 						TX_SEMI_HARD_NOTIFY_E);
526 	}
527 }
528 #else
529 static inline void
dp_tx_set_min_rates_for_critical_frames(struct dp_soc * soc,uint32_t * hal_tx_desc_cached,qdf_nbuf_t nbuf)530 dp_tx_set_min_rates_for_critical_frames(struct dp_soc *soc,
531 					uint32_t *hal_tx_desc_cached,
532 					qdf_nbuf_t nbuf)
533 {
534 }
535 #endif
536 
537 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP
538 /**
539  * dp_tx_set_particular_tx_queue() - set particular TX TQM flow queue 3 for
540  *				     TX packets, currently TCP ACK only
541  * @soc: DP soc structure pointer
542  * @hal_tx_desc: HAL descriptor where fields are set
543  * @nbuf: skb to be considered for particular TX queue
544  *
545  * Return: None
546  */
547 static inline
dp_tx_set_particular_tx_queue(struct dp_soc * soc,uint32_t * hal_tx_desc,qdf_nbuf_t nbuf)548 void dp_tx_set_particular_tx_queue(struct dp_soc *soc,
549 				   uint32_t *hal_tx_desc,
550 				   qdf_nbuf_t nbuf)
551 {
552 	if (!soc->tx_ilp_enable)
553 		return;
554 
555 	if (qdf_unlikely(QDF_NBUF_CB_GET_PACKET_TYPE(nbuf) ==
556 			 QDF_NBUF_CB_PACKET_TYPE_TCP_ACK)) {
557 		hal_tx_desc_set_flow_override_enable(hal_tx_desc, 1);
558 		hal_tx_desc_set_flow_override(hal_tx_desc, 1);
559 		hal_tx_desc_set_who_classify_info_sel(hal_tx_desc, 1);
560 	}
561 }
562 #else
563 static inline
dp_tx_set_particular_tx_queue(struct dp_soc * soc,uint32_t * hal_tx_desc,qdf_nbuf_t nbuf)564 void dp_tx_set_particular_tx_queue(struct dp_soc *soc,
565 				   uint32_t *hal_tx_desc,
566 				   qdf_nbuf_t nbuf)
567 {
568 }
569 #endif
570 
571 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
572 	defined(WLAN_MCAST_MLO)
573 #ifdef QCA_MULTIPASS_SUPPORT
574 /**
575  * dp_tx_mlo_mcast_multipass_lookup() - lookup vlan_id in mpass peer list
576  * @be_vdev: Handle to DP be_vdev structure
577  * @ptnr_vdev: DP ptnr_vdev handle
578  * @arg: pointer to dp_mlo_mpass_ buf
579  *
580  * Return: None
581  */
582 static void
dp_tx_mlo_mcast_multipass_lookup(struct dp_vdev_be * be_vdev,struct dp_vdev * ptnr_vdev,void * arg)583 dp_tx_mlo_mcast_multipass_lookup(struct dp_vdev_be *be_vdev,
584 				 struct dp_vdev *ptnr_vdev,
585 				 void *arg)
586 {
587 	struct dp_mlo_mpass_buf *ptr = (struct dp_mlo_mpass_buf *)arg;
588 	struct dp_txrx_peer *txrx_peer = NULL;
589 	struct vlan_ethhdr *veh = NULL;
590 	qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(ptr->nbuf);
591 	uint16_t vlan_id = 0;
592 	bool not_vlan = ((ptnr_vdev->tx_encap_type == htt_cmn_pkt_type_raw) ||
593 			(htons(eh->ether_type) != ETH_P_8021Q));
594 
595 	if (qdf_unlikely(not_vlan))
596 		return;
597 	veh = (struct vlan_ethhdr *)eh;
598 	vlan_id = (ntohs(veh->h_vlan_TCI) & VLAN_VID_MASK);
599 
600 	qdf_spin_lock_bh(&ptnr_vdev->mpass_peer_mutex);
601 	TAILQ_FOREACH(txrx_peer, &ptnr_vdev->mpass_peer_list,
602 		      mpass_peer_list_elem) {
603 		if (vlan_id == txrx_peer->vlan_id) {
604 			qdf_spin_unlock_bh(&ptnr_vdev->mpass_peer_mutex);
605 			ptr->vlan_id = vlan_id;
606 			return;
607 		}
608 	}
609 	qdf_spin_unlock_bh(&ptnr_vdev->mpass_peer_mutex);
610 }
611 
612 /**
613  * dp_tx_mlo_mcast_multipass_send() - send multipass MLO Mcast packets
614  * @be_vdev: Handle to DP be_vdev structure
615  * @ptnr_vdev: DP ptnr_vdev handle
616  * @arg: pointer to dp_mlo_mpass_ buf
617  *
618  * Return: None
619  */
620 static void
dp_tx_mlo_mcast_multipass_send(struct dp_vdev_be * be_vdev,struct dp_vdev * ptnr_vdev,void * arg)621 dp_tx_mlo_mcast_multipass_send(struct dp_vdev_be *be_vdev,
622 			       struct dp_vdev *ptnr_vdev,
623 			       void *arg)
624 {
625 	struct dp_mlo_mpass_buf *ptr = (struct dp_mlo_mpass_buf *)arg;
626 	struct dp_tx_msdu_info_s msdu_info;
627 	struct dp_vdev_be *be_ptnr_vdev = NULL;
628 	qdf_nbuf_t  nbuf_clone;
629 	uint16_t group_key = 0;
630 
631 	be_ptnr_vdev = dp_get_be_vdev_from_dp_vdev(ptnr_vdev);
632 	if (be_vdev != be_ptnr_vdev) {
633 		nbuf_clone = qdf_nbuf_clone(ptr->nbuf);
634 		if (qdf_unlikely(!nbuf_clone)) {
635 			dp_tx_debug("nbuf clone failed");
636 			return;
637 		}
638 	} else {
639 		nbuf_clone = ptr->nbuf;
640 	}
641 	qdf_mem_zero(&msdu_info, sizeof(msdu_info));
642 	dp_tx_get_queue(ptnr_vdev, nbuf_clone, &msdu_info.tx_queue);
643 	msdu_info.gsn = be_vdev->mlo_dev_ctxt->seq_num;
644 	msdu_info.xmit_type = qdf_nbuf_get_vdev_xmit_type(ptr->nbuf);
645 
646 
647 	if (ptr->vlan_id == MULTIPASS_WITH_VLAN_ID) {
648 		msdu_info.tid = HTT_TX_EXT_TID_INVALID;
649 		HTT_TX_MSDU_EXT2_DESC_FLAG_VALID_KEY_FLAGS_SET(
650 						msdu_info.meta_data[0], 1);
651 	} else {
652 		/* return when vlan map is not initialized */
653 		if (!ptnr_vdev->iv_vlan_map)
654 			goto nbuf_free;
655 		group_key = ptnr_vdev->iv_vlan_map[ptr->vlan_id];
656 
657 		/*
658 		 * If group key is not installed, drop the frame.
659 		 */
660 
661 		if (!group_key)
662 			goto nbuf_free;
663 
664 		dp_tx_remove_vlan_tag(ptnr_vdev, nbuf_clone);
665 		dp_tx_add_groupkey_metadata(ptnr_vdev, &msdu_info, group_key);
666 		msdu_info.exception_fw = 1;
667 	}
668 
669 	nbuf_clone = dp_tx_send_msdu_single(
670 					ptnr_vdev,
671 					nbuf_clone,
672 					&msdu_info,
673 					DP_MLO_MCAST_REINJECT_PEER_ID,
674 					NULL);
675 
676 nbuf_free:
677 	if (qdf_unlikely(nbuf_clone)) {
678 		dp_info("pkt send failed");
679 		qdf_nbuf_free(nbuf_clone);
680 		return;
681 	}
682 }
683 
684 /**
685  * dp_tx_mlo_mcast_multipass_handler - If frame needs multipass processing
686  * @soc: DP soc handle
687  * @vdev: DP vdev handle
688  * @nbuf: nbuf to be enqueued
689  *
690  * Return: true if handling is done else false
691  */
692 static bool
dp_tx_mlo_mcast_multipass_handler(struct dp_soc * soc,struct dp_vdev * vdev,qdf_nbuf_t nbuf)693 dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc,
694 				  struct dp_vdev *vdev,
695 				  qdf_nbuf_t nbuf)
696 {
697 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
698 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
699 	qdf_nbuf_t nbuf_copy = NULL;
700 	struct dp_mlo_mpass_buf mpass_buf;
701 
702 	memset(&mpass_buf, 0, sizeof(struct dp_mlo_mpass_buf));
703 	mpass_buf.vlan_id = INVALID_VLAN_ID;
704 	mpass_buf.nbuf = nbuf;
705 
706 	dp_tx_mlo_mcast_multipass_lookup(be_vdev, vdev, &mpass_buf);
707 	if (mpass_buf.vlan_id == INVALID_VLAN_ID) {
708 		dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
709 				      dp_tx_mlo_mcast_multipass_lookup,
710 				      &mpass_buf, DP_MOD_ID_TX,
711 				      DP_ALL_VDEV_ITER,
712 				      DP_VDEV_ITERATE_SKIP_SELF);
713 		/*
714 		 * Do not drop the frame when vlan_id doesn't match.
715 		 * Send the frame as it is.
716 		 */
717 		if (mpass_buf.vlan_id == INVALID_VLAN_ID)
718 			return false;
719 	}
720 
721 	/* AP can have classic clients, special clients &
722 	 * classic repeaters.
723 	 * 1. Classic clients & special client:
724 	 *	Remove vlan header, find corresponding group key
725 	 *	index, fill in metaheader and enqueue multicast
726 	 *	frame to TCL.
727 	 * 2. Classic repeater:
728 	 *	Pass through to classic repeater with vlan tag
729 	 *	intact without any group key index. Hardware
730 	 *	will know which key to use to send frame to
731 	 *	repeater.
732 	 */
733 	nbuf_copy = qdf_nbuf_copy(nbuf);
734 
735 	/*
736 	 * Send multicast frame to special peers even
737 	 * if pass through to classic repeater fails.
738 	 */
739 	if (nbuf_copy) {
740 		struct dp_mlo_mpass_buf mpass_buf_copy = {0};
741 
742 		mpass_buf_copy.vlan_id = MULTIPASS_WITH_VLAN_ID;
743 		mpass_buf_copy.nbuf = nbuf_copy;
744 		/* send frame on partner vdevs */
745 		dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
746 				      dp_tx_mlo_mcast_multipass_send,
747 				      &mpass_buf_copy, DP_MOD_ID_TX,
748 				      DP_LINK_VDEV_ITER,
749 				      DP_VDEV_ITERATE_SKIP_SELF);
750 
751 		/* send frame on mcast primary vdev */
752 		dp_tx_mlo_mcast_multipass_send(be_vdev, vdev, &mpass_buf_copy);
753 
754 		if (qdf_unlikely(be_vdev->mlo_dev_ctxt->seq_num > MAX_GSN_NUM))
755 			be_vdev->mlo_dev_ctxt->seq_num = 0;
756 		else
757 			be_vdev->mlo_dev_ctxt->seq_num++;
758 	}
759 
760 	dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
761 			      dp_tx_mlo_mcast_multipass_send,
762 			      &mpass_buf, DP_MOD_ID_TX, DP_LINK_VDEV_ITER,
763 			      DP_VDEV_ITERATE_SKIP_SELF);
764 	dp_tx_mlo_mcast_multipass_send(be_vdev, vdev, &mpass_buf);
765 
766 	if (qdf_unlikely(be_vdev->mlo_dev_ctxt->seq_num > MAX_GSN_NUM))
767 		be_vdev->mlo_dev_ctxt->seq_num = 0;
768 	else
769 		be_vdev->mlo_dev_ctxt->seq_num++;
770 
771 	return true;
772 }
773 #else
774 static bool
dp_tx_mlo_mcast_multipass_handler(struct dp_soc * soc,struct dp_vdev * vdev,qdf_nbuf_t nbuf)775 dp_tx_mlo_mcast_multipass_handler(struct dp_soc *soc, struct dp_vdev *vdev,
776 				  qdf_nbuf_t nbuf)
777 {
778 	return false;
779 }
780 #endif
781 
782 void
dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be * be_vdev,struct dp_vdev * ptnr_vdev,void * arg)783 dp_tx_mlo_mcast_pkt_send(struct dp_vdev_be *be_vdev,
784 			 struct dp_vdev *ptnr_vdev,
785 			 void *arg)
786 {
787 	qdf_nbuf_t  nbuf = (qdf_nbuf_t)arg;
788 	qdf_nbuf_t  nbuf_clone;
789 	struct dp_vdev_be *be_ptnr_vdev = NULL;
790 	struct dp_tx_msdu_info_s msdu_info;
791 
792 	be_ptnr_vdev = dp_get_be_vdev_from_dp_vdev(ptnr_vdev);
793 	if (be_vdev != be_ptnr_vdev) {
794 		nbuf_clone = qdf_nbuf_clone(nbuf);
795 		if (qdf_unlikely(!nbuf_clone)) {
796 			dp_tx_debug("nbuf clone failed");
797 			return;
798 		}
799 	} else {
800 		nbuf_clone = nbuf;
801 	}
802 
803 	/* NAWDS clients will accepts on 4 addr format MCAST packets
804 	 * This will ensure to send packets in 4 addr format to NAWDS clients.
805 	 */
806 	if (qdf_unlikely(ptnr_vdev->nawds_enabled)) {
807 		qdf_mem_zero(&msdu_info, sizeof(msdu_info));
808 		dp_tx_get_queue(ptnr_vdev, nbuf_clone, &msdu_info.tx_queue);
809 		dp_tx_nawds_handler(ptnr_vdev->pdev->soc, ptnr_vdev,
810 				    &msdu_info, nbuf_clone, DP_INVALID_PEER);
811 	}
812 
813 	if (qdf_unlikely(dp_tx_proxy_arp(ptnr_vdev, nbuf_clone) !=
814 			 QDF_STATUS_SUCCESS)) {
815 		qdf_nbuf_free(nbuf_clone);
816 		return;
817 	}
818 
819 	qdf_mem_zero(&msdu_info, sizeof(msdu_info));
820 	dp_tx_get_queue(ptnr_vdev, nbuf_clone, &msdu_info.tx_queue);
821 
822 	msdu_info.gsn = be_vdev->mlo_dev_ctxt->seq_num;
823 	msdu_info.xmit_type = qdf_nbuf_get_vdev_xmit_type(nbuf_clone);
824 
825 	DP_STATS_INC(ptnr_vdev,
826 		     tx_i[msdu_info.xmit_type].mlo_mcast.send_pkt_count, 1);
827 	nbuf_clone = dp_tx_send_msdu_single(
828 					ptnr_vdev,
829 					nbuf_clone,
830 					&msdu_info,
831 					DP_MLO_MCAST_REINJECT_PEER_ID,
832 					NULL);
833 	if (qdf_unlikely(nbuf_clone)) {
834 		DP_STATS_INC(ptnr_vdev,
835 			     tx_i[msdu_info.xmit_type].mlo_mcast.fail_pkt_count,
836 			     1);
837 		dp_info("pkt send failed");
838 		qdf_nbuf_free(nbuf_clone);
839 		return;
840 	}
841 }
842 
843 static inline void
dp_tx_vdev_id_set_hal_tx_desc(uint32_t * hal_tx_desc_cached,struct dp_vdev * vdev,struct dp_tx_msdu_info_s * msdu_info)844 dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,
845 			      struct dp_vdev *vdev,
846 			      struct dp_tx_msdu_info_s *msdu_info)
847 {
848 	hal_tx_desc_set_vdev_id(hal_tx_desc_cached, msdu_info->vdev_id);
849 }
850 
dp_tx_mlo_mcast_handler_be(struct dp_soc * soc,struct dp_vdev * vdev,qdf_nbuf_t nbuf)851 void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
852 				struct dp_vdev *vdev,
853 				qdf_nbuf_t nbuf)
854 {
855 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
856 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
857 
858 	if (qdf_unlikely(vdev->multipass_en) &&
859 	    dp_tx_mlo_mcast_multipass_handler(soc, vdev, nbuf))
860 		return;
861 	/* send frame on partner vdevs */
862 	dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
863 			      dp_tx_mlo_mcast_pkt_send,
864 			      nbuf, DP_MOD_ID_REINJECT, DP_LINK_VDEV_ITER,
865 			      DP_VDEV_ITERATE_SKIP_SELF);
866 
867 	/* send frame on mcast primary vdev */
868 	dp_tx_mlo_mcast_pkt_send(be_vdev, vdev, nbuf);
869 
870 	if (qdf_unlikely(be_vdev->mlo_dev_ctxt->seq_num > MAX_GSN_NUM))
871 		be_vdev->mlo_dev_ctxt->seq_num = 0;
872 	else
873 		be_vdev->mlo_dev_ctxt->seq_num++;
874 }
875 
dp_tx_mlo_is_mcast_primary_be(struct dp_soc * soc,struct dp_vdev * vdev)876 bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
877 				   struct dp_vdev *vdev)
878 {
879 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
880 
881 	if (be_vdev->mcast_primary)
882 		return true;
883 
884 	return false;
885 }
886 
887 #if defined(CONFIG_MLO_SINGLE_DEV)
888 static void
dp_tx_mlo_mcast_enhance_be(struct dp_vdev_be * be_vdev,struct dp_vdev * ptnr_vdev,void * arg)889 dp_tx_mlo_mcast_enhance_be(struct dp_vdev_be *be_vdev,
890 			   struct dp_vdev *ptnr_vdev,
891 			   void *arg)
892 {
893 	struct dp_vdev *vdev = (struct dp_vdev *)be_vdev;
894 	qdf_nbuf_t  nbuf = (qdf_nbuf_t)arg;
895 
896 	if (vdev == ptnr_vdev)
897 		return;
898 
899 	/*
900 	 * Hold the reference to avoid free of nbuf in
901 	 * dp_tx_mcast_enhance() in case of successful
902 	 * conversion
903 	 */
904 	qdf_nbuf_ref(nbuf);
905 
906 	if (qdf_unlikely(!dp_tx_mcast_enhance(ptnr_vdev, nbuf)))
907 		return;
908 
909 	qdf_nbuf_free(nbuf);
910 }
911 
912 qdf_nbuf_t
dp_tx_mlo_mcast_send_be(struct dp_soc * soc,struct dp_vdev * vdev,qdf_nbuf_t nbuf,struct cdp_tx_exception_metadata * tx_exc_metadata)913 dp_tx_mlo_mcast_send_be(struct dp_soc *soc, struct dp_vdev *vdev,
914 			qdf_nbuf_t nbuf,
915 			struct cdp_tx_exception_metadata *tx_exc_metadata)
916 {
917 	struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
918 	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
919 
920 	if (!tx_exc_metadata->is_mlo_mcast)
921 		return nbuf;
922 
923 	if (!be_vdev->mcast_primary) {
924 		qdf_nbuf_free(nbuf);
925 		return NULL;
926 	}
927 
928 	/*
929 	 * In the single netdev model avoid reinjection path as mcast
930 	 * packet is identified in upper layers while peer search to find
931 	 * primary TQM based on dest mac addr
932 	 *
933 	 * New bonding interface added into the bridge so MCSD will update
934 	 * snooping table and wifi driver populates the entries in appropriate
935 	 * child net devices.
936 	 */
937 	if (vdev->mcast_enhancement_en) {
938 		/*
939 		 * As dp_tx_mcast_enhance() can consume the nbuf incase of
940 		 * successful conversion hold the reference of nbuf.
941 		 *
942 		 * Hold the reference to tx on partner links
943 		 */
944 		qdf_nbuf_ref(nbuf);
945 		if (qdf_unlikely(!dp_tx_mcast_enhance(vdev, nbuf))) {
946 			dp_mlo_iter_ptnr_vdev(be_soc, be_vdev,
947 					      dp_tx_mlo_mcast_enhance_be,
948 					      nbuf, DP_MOD_ID_TX,
949 					      DP_ALL_VDEV_ITER,
950 					      DP_VDEV_ITERATE_SKIP_SELF);
951 			qdf_nbuf_free(nbuf);
952 			return NULL;
953 		}
954 		/* release reference taken above */
955 		qdf_nbuf_free(nbuf);
956 	}
957 	dp_tx_mlo_mcast_handler_be(soc, vdev, nbuf);
958 	return NULL;
959 }
960 #endif
961 #else
962 static inline void
dp_tx_vdev_id_set_hal_tx_desc(uint32_t * hal_tx_desc_cached,struct dp_vdev * vdev,struct dp_tx_msdu_info_s * msdu_info)963 dp_tx_vdev_id_set_hal_tx_desc(uint32_t *hal_tx_desc_cached,
964 			      struct dp_vdev *vdev,
965 			      struct dp_tx_msdu_info_s *msdu_info)
966 {
967 	hal_tx_desc_set_vdev_id(hal_tx_desc_cached, vdev->vdev_id);
968 }
969 #endif
970 #if defined(WLAN_FEATURE_11BE_MLO) && !defined(WLAN_MLO_MULTI_CHIP) && \
971 	!defined(WLAN_MCAST_MLO)
dp_tx_mlo_mcast_handler_be(struct dp_soc * soc,struct dp_vdev * vdev,qdf_nbuf_t nbuf)972 void dp_tx_mlo_mcast_handler_be(struct dp_soc *soc,
973 				struct dp_vdev *vdev,
974 				qdf_nbuf_t nbuf)
975 {
976 }
977 
dp_tx_mlo_is_mcast_primary_be(struct dp_soc * soc,struct dp_vdev * vdev)978 bool dp_tx_mlo_is_mcast_primary_be(struct dp_soc *soc,
979 				   struct dp_vdev *vdev)
980 {
981 	return false;
982 }
983 #endif
984 
985 #ifdef CONFIG_SAWF
986 /**
987  * dp_sawf_config_be - Configure sawf specific fields in tcl
988  *
989  * @soc: DP soc handle
990  * @hal_tx_desc_cached: tx descriptor
991  * @fw_metadata: firmware metadata
992  * @nbuf: skb buffer
993  * @msdu_info: msdu info
994  *
995  * Return: tid value in mark metadata
996  */
dp_sawf_config_be(struct dp_soc * soc,uint32_t * hal_tx_desc_cached,uint16_t * fw_metadata,qdf_nbuf_t nbuf,struct dp_tx_msdu_info_s * msdu_info)997 uint8_t dp_sawf_config_be(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
998 			  uint16_t *fw_metadata, qdf_nbuf_t nbuf,
999 			  struct dp_tx_msdu_info_s *msdu_info)
1000 {
1001 	uint8_t q_id = 0;
1002 	uint8_t tid = HTT_TX_EXT_TID_INVALID;
1003 
1004 	q_id = dp_sawf_queue_id_get(nbuf);
1005 
1006 	if (q_id == DP_SAWF_DEFAULT_Q_INVALID)
1007 		return HTT_TX_EXT_TID_INVALID;
1008 
1009 	tid = (q_id & (CDP_DATA_TID_MAX - 1));
1010 	if (msdu_info)
1011 		msdu_info->tid = tid;
1012 
1013 	hal_tx_desc_set_hlos_tid(hal_tx_desc_cached,
1014 				 (q_id & (CDP_DATA_TID_MAX - 1)));
1015 
1016 	if ((q_id >= DP_SAWF_DEFAULT_QUEUE_MIN) &&
1017 	    (q_id < DP_SAWF_DEFAULT_QUEUE_MAX))
1018 		return tid;
1019 
1020 	if (!wlan_cfg_get_sawf_config(soc->wlan_cfg_ctx))
1021 		return tid;
1022 
1023 	if (fw_metadata)
1024 		dp_sawf_tcl_cmd(fw_metadata, nbuf);
1025 	hal_tx_desc_set_flow_override_enable(hal_tx_desc_cached,
1026 					     DP_TX_FLOW_OVERRIDE_ENABLE);
1027 	hal_tx_desc_set_flow_override(hal_tx_desc_cached,
1028 				      DP_TX_FLOW_OVERRIDE_GET(q_id));
1029 	hal_tx_desc_set_who_classify_info_sel(hal_tx_desc_cached,
1030 					      DP_TX_WHO_CLFY_INF_SEL_GET(q_id));
1031 
1032 	return tid;
1033 }
1034 
1035 #else
1036 
1037 static inline
dp_sawf_config_be(struct dp_soc * soc,uint32_t * hal_tx_desc_cached,uint16_t * fw_metadata,qdf_nbuf_t nbuf,struct dp_tx_msdu_info_s * msdu_info)1038 uint8_t dp_sawf_config_be(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
1039 			  uint16_t *fw_metadata, qdf_nbuf_t nbuf,
1040 			  struct dp_tx_msdu_info_s *msdu_info)
1041 {
1042 	return HTT_TX_EXT_TID_INVALID;
1043 }
1044 
1045 static inline
dp_sawf_tx_enqueue_peer_stats(struct dp_soc * soc,struct dp_tx_desc_s * tx_desc)1046 QDF_STATUS dp_sawf_tx_enqueue_peer_stats(struct dp_soc *soc,
1047 					 struct dp_tx_desc_s *tx_desc)
1048 {
1049 	return QDF_STATUS_SUCCESS;
1050 }
1051 
1052 static inline
dp_sawf_tx_enqueue_fail_peer_stats(struct dp_soc * soc,struct dp_tx_desc_s * tx_desc)1053 QDF_STATUS dp_sawf_tx_enqueue_fail_peer_stats(struct dp_soc *soc,
1054 					      struct dp_tx_desc_s *tx_desc)
1055 {
1056 	return QDF_STATUS_SUCCESS;
1057 }
1058 #endif
1059 
1060 #ifdef WLAN_SUPPORT_PPEDS
1061 
1062 /**
1063  * dp_ppeds_stats() - Accounting fw2wbm_tx_drop drops in Tx path
1064  * @soc: Handle to DP Soc structure
1065  * @peer_id: Peer ID in the descriptor
1066  *
1067  * Return: NONE
1068  */
1069 static inline
dp_ppeds_stats(struct dp_soc * soc,uint16_t peer_id)1070 void dp_ppeds_stats(struct dp_soc *soc, uint16_t peer_id)
1071 {
1072 	struct dp_vdev *vdev = NULL;
1073 	struct dp_txrx_peer *txrx_peer = NULL;
1074 	dp_txrx_ref_handle txrx_ref_handle = NULL;
1075 
1076 	DP_STATS_INC(soc, tx.fw2wbm_tx_drop, 1);
1077 	txrx_peer = dp_txrx_peer_get_ref_by_id(soc,
1078 					       peer_id,
1079 					       &txrx_ref_handle,
1080 					       DP_MOD_ID_TX_COMP);
1081 	if (txrx_peer) {
1082 		vdev = txrx_peer->vdev;
1083 		DP_STATS_INC(vdev, tx_i[DP_XMIT_LINK].dropped.fw2wbm_tx_drop, 1);
1084 		dp_txrx_peer_unref_delete(txrx_ref_handle, DP_MOD_ID_TX_COMP);
1085 	}
1086 }
1087 
dp_ppeds_tx_comp_handler(struct dp_soc_be * be_soc,uint32_t quota)1088 int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota)
1089 {
1090 	uint32_t num_avail_for_reap = 0;
1091 	void *tx_comp_hal_desc;
1092 	uint8_t buf_src, status = 0;
1093 	uint32_t count = 0;
1094 	struct dp_tx_desc_s *tx_desc = NULL;
1095 	struct dp_tx_desc_s *head_desc = NULL;
1096 	struct dp_tx_desc_s *tail_desc = NULL;
1097 	struct dp_soc *soc = &be_soc->soc;
1098 	void *last_prefetch_hw_desc = NULL;
1099 	struct dp_tx_desc_s *last_prefetch_sw_desc = NULL;
1100 	qdf_nbuf_t  nbuf;
1101 	hal_soc_handle_t hal_soc = soc->hal_soc;
1102 	hal_ring_handle_t hal_ring_hdl =
1103 				be_soc->ppeds_wbm_release_ring.hal_srng;
1104 	struct dp_txrx_peer *txrx_peer = NULL;
1105 	uint16_t peer_id = CDP_INVALID_PEER;
1106 	dp_txrx_ref_handle txrx_ref_handle = NULL;
1107 	struct dp_vdev *vdev = NULL;
1108 	struct dp_pdev *pdev = NULL;
1109 	struct dp_srng *srng;
1110 
1111 	if (qdf_unlikely(dp_srng_access_start(NULL, soc, hal_ring_hdl))) {
1112 		dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
1113 		return 0;
1114 	}
1115 
1116 	num_avail_for_reap = hal_srng_dst_num_valid(hal_soc, hal_ring_hdl, 0);
1117 
1118 	if (num_avail_for_reap >= quota)
1119 		num_avail_for_reap = quota;
1120 
1121 	dp_srng_dst_inv_cached_descs(soc, hal_ring_hdl, num_avail_for_reap);
1122 
1123 	last_prefetch_hw_desc = dp_srng_dst_prefetch(hal_soc, hal_ring_hdl,
1124 						     num_avail_for_reap);
1125 
1126 	srng = &be_soc->ppeds_wbm_release_ring;
1127 
1128 	if (srng) {
1129 		hal_update_ring_util(soc->hal_soc, srng->hal_srng,
1130 				     WBM2SW_RELEASE,
1131 				     &be_soc->ppeds_wbm_release_ring.stats);
1132 	}
1133 
1134 	while (qdf_likely(num_avail_for_reap--)) {
1135 		tx_comp_hal_desc =  dp_srng_dst_get_next(soc, hal_ring_hdl);
1136 		if (qdf_unlikely(!tx_comp_hal_desc))
1137 			break;
1138 
1139 		buf_src = hal_tx_comp_get_buffer_source(hal_soc,
1140 							tx_comp_hal_desc);
1141 
1142 		if (qdf_unlikely(buf_src != HAL_TX_COMP_RELEASE_SOURCE_TQM &&
1143 				 buf_src != HAL_TX_COMP_RELEASE_SOURCE_FW)) {
1144 			dp_err("Tx comp release_src != TQM | FW but from %d",
1145 			       buf_src);
1146 			dp_assert_always_internal_ds_stat(0, be_soc,
1147 							  tx.tx_comp_buf_src);
1148 			continue;
1149 		}
1150 
1151 		dp_tx_comp_get_params_from_hal_desc_be(soc, tx_comp_hal_desc,
1152 						       &tx_desc);
1153 
1154 		if (!tx_desc) {
1155 			dp_err("unable to retrieve tx_desc!");
1156 			dp_assert_always_internal_ds_stat(0, be_soc,
1157 							  tx.tx_comp_desc_null);
1158 			continue;
1159 		}
1160 
1161 		if (qdf_unlikely(!(tx_desc->flags &
1162 				   DP_TX_DESC_FLAG_ALLOCATED) ||
1163 				 !(tx_desc->flags & DP_TX_DESC_FLAG_PPEDS))) {
1164 			dp_assert_always_internal_ds_stat(0, be_soc,
1165 						tx.tx_comp_invalid_flag);
1166 			continue;
1167 		}
1168 
1169 		tx_desc->buffer_src = buf_src;
1170 
1171 		if (qdf_unlikely(buf_src == HAL_TX_COMP_RELEASE_SOURCE_FW)) {
1172 			status = hal_tx_comp_get_tx_status(tx_comp_hal_desc);
1173 			if (status != HTT_TX_FW2WBM_TX_STATUS_OK)
1174 				dp_ppeds_stats(soc, tx_desc->peer_id);
1175 
1176 			nbuf = dp_ppeds_tx_desc_free(soc, tx_desc);
1177 			qdf_nbuf_free(nbuf);
1178 		} else {
1179 			tx_desc->tx_status =
1180 				hal_tx_comp_get_tx_status(tx_comp_hal_desc);
1181 
1182 			/*
1183 			 * Add desc sync to account for extended statistics
1184 			 * during Tx completion.
1185 			 */
1186 			if (peer_id != tx_desc->peer_id) {
1187 				if (txrx_peer) {
1188 					dp_txrx_peer_unref_delete(txrx_ref_handle,
1189 								  DP_MOD_ID_TX_COMP);
1190 					txrx_peer = NULL;
1191 					vdev = NULL;
1192 					pdev = NULL;
1193 				}
1194 				peer_id = tx_desc->peer_id;
1195 				txrx_peer =
1196 					dp_txrx_peer_get_ref_by_id(soc, peer_id,
1197 								   &txrx_ref_handle,
1198 								   DP_MOD_ID_TX_COMP);
1199 				if (txrx_peer) {
1200 					vdev = txrx_peer->vdev;
1201 					if (!vdev)
1202 						goto next_desc;
1203 
1204 					pdev = vdev->pdev;
1205 					if (!pdev)
1206 						goto next_desc;
1207 
1208 					dp_tx_desc_update_fast_comp_flag(soc,
1209 									 tx_desc,
1210 									 !pdev->enhanced_stats_en);
1211 					if (pdev->enhanced_stats_en) {
1212 						hal_tx_comp_desc_sync(tx_comp_hal_desc,
1213 								      &tx_desc->comp, 1);
1214 					}
1215 				}
1216 			} else if (txrx_peer && vdev && pdev) {
1217 				dp_tx_desc_update_fast_comp_flag(soc,
1218 								 tx_desc,
1219 								 !pdev->enhanced_stats_en);
1220 				if (pdev->enhanced_stats_en) {
1221 					hal_tx_comp_desc_sync(tx_comp_hal_desc,
1222 							      &tx_desc->comp, 1);
1223 				}
1224 			}
1225 next_desc:
1226 			if (!head_desc) {
1227 				head_desc = tx_desc;
1228 				tail_desc = tx_desc;
1229 			}
1230 
1231 			tail_desc->next = tx_desc;
1232 			tx_desc->next = NULL;
1233 			tail_desc = tx_desc;
1234 
1235 			count++;
1236 
1237 			dp_tx_prefetch_hw_sw_nbuf_desc(soc, hal_soc,
1238 						       num_avail_for_reap,
1239 						       hal_ring_hdl,
1240 						       &last_prefetch_hw_desc,
1241 						       &last_prefetch_sw_desc,
1242 						       NULL);
1243 		}
1244 	}
1245 
1246 	dp_srng_access_end(NULL, soc, hal_ring_hdl);
1247 
1248 	if (txrx_peer)
1249 		dp_txrx_peer_unref_delete(txrx_ref_handle,
1250 					  DP_MOD_ID_TX_COMP);
1251 	if (head_desc)
1252 		dp_tx_comp_process_desc_list(soc, head_desc,
1253 					     CDP_MAX_TX_COMP_PPE_RING);
1254 
1255 	return count;
1256 }
1257 #endif
1258 
1259 #if defined(QCA_SUPPORT_WDS_EXTENDED)
1260 static inline void
dp_get_peer_from_tx_exc_meta(struct dp_soc * soc,uint32_t * hal_tx_desc_cached,struct cdp_tx_exception_metadata * tx_exc_metadata,uint16_t * ast_idx,uint16_t * ast_hash)1261 dp_get_peer_from_tx_exc_meta(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
1262 			     struct cdp_tx_exception_metadata *tx_exc_metadata,
1263 			     uint16_t *ast_idx, uint16_t *ast_hash)
1264 {
1265 	struct dp_peer *peer = NULL;
1266 
1267 	if (tx_exc_metadata->is_wds_extended) {
1268 		peer = dp_peer_get_ref_by_id(soc, tx_exc_metadata->peer_id,
1269 					     DP_MOD_ID_TX);
1270 		if (peer) {
1271 			*ast_idx = peer->ast_idx;
1272 			*ast_hash = peer->ast_hash;
1273 			hal_tx_desc_set_index_lookup_override
1274 							(soc->hal_soc,
1275 							 hal_tx_desc_cached,
1276 							 0x1);
1277 			dp_peer_unref_delete(peer, DP_MOD_ID_TX);
1278 		}
1279 	} else {
1280 		return;
1281 	}
1282 }
1283 
1284 #else
1285 static inline void
dp_get_peer_from_tx_exc_meta(struct dp_soc * soc,uint32_t * hal_tx_desc_cached,struct cdp_tx_exception_metadata * tx_exc_metadata,uint16_t * ast_idx,uint16_t * ast_hash)1286 dp_get_peer_from_tx_exc_meta(struct dp_soc *soc, uint32_t *hal_tx_desc_cached,
1287 			     struct cdp_tx_exception_metadata *tx_exc_metadata,
1288 			     uint16_t *ast_idx, uint16_t *ast_hash)
1289 {
1290 }
1291 #endif
1292 
1293 QDF_STATUS
dp_tx_hw_enqueue_be(struct dp_soc * soc,struct dp_vdev * vdev,struct dp_tx_desc_s * tx_desc,uint16_t fw_metadata,struct cdp_tx_exception_metadata * tx_exc_metadata,struct dp_tx_msdu_info_s * msdu_info)1294 dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
1295 		    struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,
1296 		    struct cdp_tx_exception_metadata *tx_exc_metadata,
1297 		    struct dp_tx_msdu_info_s *msdu_info)
1298 {
1299 	void *hal_tx_desc;
1300 	uint32_t *hal_tx_desc_cached;
1301 	int coalesce = 0;
1302 	struct dp_tx_queue *tx_q = &msdu_info->tx_queue;
1303 	uint8_t ring_id = tx_q->ring_id;
1304 	uint8_t tid;
1305 	struct dp_vdev_be *be_vdev;
1306 	uint8_t cached_desc[HAL_TX_DESC_LEN_BYTES] = { 0 };
1307 	uint8_t bm_id = dp_tx_get_rbm_id_be(soc, ring_id);
1308 	hal_ring_handle_t hal_ring_hdl = NULL;
1309 	QDF_STATUS status = QDF_STATUS_E_RESOURCES;
1310 	uint8_t num_desc_bytes = HAL_TX_DESC_LEN_BYTES;
1311 	uint16_t ast_idx = vdev->bss_ast_idx;
1312 	uint16_t ast_hash = vdev->bss_ast_hash;
1313 
1314 	be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
1315 
1316 	if (!dp_tx_is_desc_id_valid(soc, tx_desc->id)) {
1317 		dp_err_rl("Invalid tx desc id:%d", tx_desc->id);
1318 		return QDF_STATUS_E_RESOURCES;
1319 	}
1320 
1321 	if (qdf_unlikely(tx_exc_metadata)) {
1322 		qdf_assert_always((tx_exc_metadata->tx_encap_type ==
1323 				   CDP_INVALID_TX_ENCAP_TYPE) ||
1324 				   (tx_exc_metadata->tx_encap_type ==
1325 				    vdev->tx_encap_type));
1326 
1327 		if (tx_exc_metadata->tx_encap_type == htt_cmn_pkt_type_raw)
1328 			qdf_assert_always((tx_exc_metadata->sec_type ==
1329 					   CDP_INVALID_SEC_TYPE) ||
1330 					   tx_exc_metadata->sec_type ==
1331 					   vdev->sec_type);
1332 		dp_get_peer_from_tx_exc_meta(soc, (void *)cached_desc,
1333 					     tx_exc_metadata,
1334 					     &ast_idx, &ast_hash);
1335 	}
1336 
1337 	hal_tx_desc_cached = (void *)cached_desc;
1338 
1339 	if (dp_sawf_tag_valid_get(tx_desc->nbuf)) {
1340 		dp_sawf_config_be(soc, hal_tx_desc_cached,
1341 				  &fw_metadata, tx_desc->nbuf, msdu_info);
1342 		dp_sawf_tx_enqueue_peer_stats(soc, tx_desc);
1343 	}
1344 
1345 	hal_tx_desc_set_buf_addr_be(soc->hal_soc, hal_tx_desc_cached,
1346 				    tx_desc->dma_addr, bm_id, tx_desc->id,
1347 				    (tx_desc->flags & DP_TX_DESC_FLAG_FRAG));
1348 	hal_tx_desc_set_lmac_id_be(soc->hal_soc, hal_tx_desc_cached,
1349 				   vdev->lmac_id);
1350 
1351 	hal_tx_desc_set_search_index_be(soc->hal_soc, hal_tx_desc_cached,
1352 					ast_idx);
1353 	/*
1354 	 * Bank_ID is used as DSCP_TABLE number in beryllium
1355 	 * So there is no explicit field used for DSCP_TID_TABLE_NUM.
1356 	 */
1357 
1358 	hal_tx_desc_set_cache_set_num(soc->hal_soc, hal_tx_desc_cached,
1359 				      (ast_hash & 0xF));
1360 
1361 	hal_tx_desc_set_fw_metadata(hal_tx_desc_cached, fw_metadata);
1362 	hal_tx_desc_set_buf_length(hal_tx_desc_cached, tx_desc->length);
1363 	hal_tx_desc_set_buf_offset(hal_tx_desc_cached, tx_desc->pkt_offset);
1364 
1365 	if (tx_desc->flags & DP_TX_DESC_FLAG_TO_FW)
1366 		hal_tx_desc_set_to_fw(hal_tx_desc_cached, 1);
1367 
1368 	/* verify checksum offload configuration*/
1369 	if ((qdf_nbuf_get_tx_cksum(tx_desc->nbuf) ==
1370 				   QDF_NBUF_TX_CKSUM_TCP_UDP) ||
1371 	      qdf_nbuf_is_tso(tx_desc->nbuf)) {
1372 		hal_tx_desc_set_l3_checksum_en(hal_tx_desc_cached, 1);
1373 		hal_tx_desc_set_l4_checksum_en(hal_tx_desc_cached, 1);
1374 	}
1375 
1376 	hal_tx_desc_set_bank_id(hal_tx_desc_cached, vdev->bank_id);
1377 
1378 	dp_tx_vdev_id_set_hal_tx_desc(hal_tx_desc_cached, vdev, msdu_info);
1379 
1380 	tid = msdu_info->tid;
1381 	if (tid != HTT_TX_EXT_TID_INVALID)
1382 		hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid);
1383 
1384 	dp_tx_set_min_rates_for_critical_frames(soc, hal_tx_desc_cached,
1385 						tx_desc->nbuf);
1386 	dp_tx_set_particular_tx_queue(soc, hal_tx_desc_cached,
1387 				      tx_desc->nbuf);
1388 	dp_tx_desc_set_ktimestamp(vdev, tx_desc);
1389 
1390 	hal_ring_hdl = dp_tx_get_hal_ring_hdl(soc, ring_id);
1391 
1392 	if (qdf_unlikely(dp_tx_hal_ring_access_start(soc, hal_ring_hdl))) {
1393 		dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
1394 		DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
1395 		DP_STATS_INC(vdev,
1396 			     tx_i[msdu_info->xmit_type].dropped.enqueue_fail,
1397 			     1);
1398 		dp_sawf_tx_enqueue_fail_peer_stats(soc, tx_desc);
1399 		return status;
1400 	}
1401 
1402 	hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_ring_hdl);
1403 	if (qdf_unlikely(!hal_tx_desc)) {
1404 		dp_verbose_debug("TCL ring full ring_id:%d", ring_id);
1405 		DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
1406 		DP_STATS_INC(vdev,
1407 			     tx_i[msdu_info->xmit_type].dropped.enqueue_fail,
1408 			     1);
1409 		dp_sawf_tx_enqueue_fail_peer_stats(soc, tx_desc);
1410 		goto ring_access_fail;
1411 	}
1412 
1413 	tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
1414 	dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
1415 
1416 	/* Sync cached descriptor with HW */
1417 	hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc, num_desc_bytes);
1418 
1419 	coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid,
1420 					    msdu_info, ring_id);
1421 
1422 	DP_STATS_INC_PKT(vdev, tx_i[msdu_info->xmit_type].processed, 1,
1423 			 dp_tx_get_pkt_len(tx_desc));
1424 	DP_STATS_INC(soc, tx.tcl_enq[ring_id], 1);
1425 	dp_tx_update_stats(soc, tx_desc, ring_id);
1426 	status = QDF_STATUS_SUCCESS;
1427 
1428 	dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,
1429 				 hal_ring_hdl, soc, ring_id);
1430 
1431 ring_access_fail:
1432 	dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl, coalesce);
1433 	dp_pkt_add_timestamp(vdev, QDF_PKT_TX_DRIVER_EXIT,
1434 			     qdf_get_log_timestamp(), tx_desc->nbuf);
1435 	return status;
1436 }
1437 
1438 #ifdef IPA_OFFLOAD
1439 static void
dp_tx_get_ipa_bank_config(struct dp_soc_be * be_soc,union hal_tx_bank_config * bank_config)1440 dp_tx_get_ipa_bank_config(struct dp_soc_be *be_soc,
1441 			  union hal_tx_bank_config *bank_config)
1442 {
1443 	bank_config->epd = 0;
1444 	bank_config->encap_type = wlan_cfg_pkt_type(be_soc->soc.wlan_cfg_ctx);
1445 	bank_config->encrypt_type = 0;
1446 
1447 	bank_config->src_buffer_swap = 0;
1448 	bank_config->link_meta_swap = 0;
1449 
1450 	bank_config->index_lookup_enable = 0;
1451 	bank_config->mcast_pkt_ctrl = HAL_TX_MCAST_CTRL_FW_EXCEPTION;
1452 	bank_config->addrx_en = 1;
1453 	bank_config->addry_en = 1;
1454 
1455 	bank_config->mesh_enable = 0;
1456 	bank_config->dscp_tid_map_id = 0;
1457 	bank_config->vdev_id_check_en = 0;
1458 	bank_config->pmac_id = 0;
1459 }
1460 
dp_tx_init_ipa_bank_profile(struct dp_soc_be * be_soc)1461 static void dp_tx_init_ipa_bank_profile(struct dp_soc_be *be_soc)
1462 {
1463 	union hal_tx_bank_config ipa_config = {0};
1464 	int bid;
1465 
1466 	if (!wlan_cfg_is_ipa_enabled(be_soc->soc.wlan_cfg_ctx)) {
1467 		be_soc->ipa_bank_id = DP_BE_INVALID_BANK_ID;
1468 		return;
1469 	}
1470 
1471 	dp_tx_get_ipa_bank_config(be_soc, &ipa_config);
1472 
1473 	/* Let IPA use last HOST owned bank */
1474 	bid = be_soc->num_bank_profiles - 1;
1475 
1476 	be_soc->bank_profiles[bid].is_configured = true;
1477 	be_soc->bank_profiles[bid].bank_config.val = ipa_config.val;
1478 	hal_tx_populate_bank_register(be_soc->soc.hal_soc,
1479 				      &be_soc->bank_profiles[bid].bank_config,
1480 				      bid);
1481 	qdf_atomic_inc(&be_soc->bank_profiles[bid].ref_count);
1482 
1483 	dp_info("IPA bank at slot %d config:0x%x", bid,
1484 		be_soc->bank_profiles[bid].bank_config.val);
1485 
1486 	be_soc->ipa_bank_id = bid;
1487 }
1488 #else /* !IPA_OFFLOAD */
dp_tx_init_ipa_bank_profile(struct dp_soc_be * be_soc)1489 static inline void dp_tx_init_ipa_bank_profile(struct dp_soc_be *be_soc)
1490 {
1491 }
1492 #endif /* IPA_OFFLOAD */
1493 
dp_tx_init_bank_profiles(struct dp_soc_be * be_soc)1494 QDF_STATUS dp_tx_init_bank_profiles(struct dp_soc_be *be_soc)
1495 {
1496 	int i, num_tcl_banks;
1497 
1498 	num_tcl_banks = hal_tx_get_num_tcl_banks(be_soc->soc.hal_soc);
1499 
1500 	dp_assert_always_internal(num_tcl_banks);
1501 	be_soc->num_bank_profiles = num_tcl_banks;
1502 
1503 	be_soc->bank_profiles = qdf_mem_malloc(num_tcl_banks *
1504 					       sizeof(*be_soc->bank_profiles));
1505 	if (!be_soc->bank_profiles) {
1506 		dp_err("unable to allocate memory for DP TX Profiles!");
1507 		return QDF_STATUS_E_NOMEM;
1508 	}
1509 
1510 	DP_TX_BANK_LOCK_CREATE(&be_soc->tx_bank_lock);
1511 
1512 	for (i = 0; i < num_tcl_banks; i++) {
1513 		be_soc->bank_profiles[i].is_configured = false;
1514 		qdf_atomic_init(&be_soc->bank_profiles[i].ref_count);
1515 	}
1516 	dp_info("initialized %u bank profiles", be_soc->num_bank_profiles);
1517 
1518 	dp_tx_init_ipa_bank_profile(be_soc);
1519 
1520 	return QDF_STATUS_SUCCESS;
1521 }
1522 
dp_tx_deinit_bank_profiles(struct dp_soc_be * be_soc)1523 void dp_tx_deinit_bank_profiles(struct dp_soc_be *be_soc)
1524 {
1525 	qdf_mem_free(be_soc->bank_profiles);
1526 	DP_TX_BANK_LOCK_DESTROY(&be_soc->tx_bank_lock);
1527 }
1528 
1529 static
dp_tx_get_vdev_bank_config(struct dp_vdev_be * be_vdev,union hal_tx_bank_config * bank_config)1530 void dp_tx_get_vdev_bank_config(struct dp_vdev_be *be_vdev,
1531 				union hal_tx_bank_config *bank_config)
1532 {
1533 	struct dp_vdev *vdev = &be_vdev->vdev;
1534 
1535 	bank_config->epd = 0;
1536 
1537 	bank_config->encap_type = vdev->tx_encap_type;
1538 
1539 	/* Only valid for raw frames. Needs work for RAW mode */
1540 	if (vdev->tx_encap_type == htt_cmn_pkt_type_raw) {
1541 		bank_config->encrypt_type = sec_type_map[vdev->sec_type];
1542 	} else {
1543 		bank_config->encrypt_type = 0;
1544 	}
1545 
1546 	bank_config->src_buffer_swap = 0;
1547 	bank_config->link_meta_swap = 0;
1548 
1549 	if ((vdev->search_type == HAL_TX_ADDR_INDEX_SEARCH) &&
1550 	    vdev->opmode == wlan_op_mode_sta) {
1551 		bank_config->index_lookup_enable = 1;
1552 		bank_config->mcast_pkt_ctrl = HAL_TX_MCAST_CTRL_MEC_NOTIFY;
1553 		bank_config->addrx_en = 0;
1554 		bank_config->addry_en = 0;
1555 	} else {
1556 		bank_config->index_lookup_enable = 0;
1557 		bank_config->mcast_pkt_ctrl = HAL_TX_MCAST_CTRL_FW_EXCEPTION;
1558 		bank_config->addrx_en =
1559 			(vdev->hal_desc_addr_search_flags &
1560 			 HAL_TX_DESC_ADDRX_EN) ? 1 : 0;
1561 		bank_config->addry_en =
1562 			(vdev->hal_desc_addr_search_flags &
1563 			 HAL_TX_DESC_ADDRY_EN) ? 1 : 0;
1564 	}
1565 
1566 	bank_config->mesh_enable = vdev->mesh_vdev ? 1 : 0;
1567 
1568 	bank_config->dscp_tid_map_id = vdev->dscp_tid_map_id;
1569 
1570 	/* Disabling vdev id check for now. Needs revist. */
1571 	bank_config->vdev_id_check_en = be_vdev->vdev_id_check_en;
1572 
1573 	bank_config->pmac_id = vdev->lmac_id;
1574 }
1575 
dp_tx_get_bank_profile(struct dp_soc_be * be_soc,struct dp_vdev_be * be_vdev)1576 int dp_tx_get_bank_profile(struct dp_soc_be *be_soc,
1577 			   struct dp_vdev_be *be_vdev)
1578 {
1579 	char *temp_str = "";
1580 	bool found_match = false;
1581 	int bank_id = DP_BE_INVALID_BANK_ID;
1582 	int i;
1583 	int unconfigured_slot = DP_BE_INVALID_BANK_ID;
1584 	int zero_ref_count_slot = DP_BE_INVALID_BANK_ID;
1585 	union hal_tx_bank_config vdev_config = {0};
1586 
1587 	/* convert vdev params into hal_tx_bank_config */
1588 	dp_tx_get_vdev_bank_config(be_vdev, &vdev_config);
1589 
1590 	DP_TX_BANK_LOCK_ACQUIRE(&be_soc->tx_bank_lock);
1591 	/* go over all banks and find a matching/unconfigured/unused bank */
1592 	for (i = 0; i < be_soc->num_bank_profiles; i++) {
1593 		if (be_soc->bank_profiles[i].is_configured &&
1594 		    (be_soc->bank_profiles[i].bank_config.val ^
1595 						vdev_config.val) == 0) {
1596 			found_match = true;
1597 			break;
1598 		}
1599 
1600 		if (unconfigured_slot == DP_BE_INVALID_BANK_ID &&
1601 		    !be_soc->bank_profiles[i].is_configured)
1602 			unconfigured_slot = i;
1603 		else if (zero_ref_count_slot  == DP_BE_INVALID_BANK_ID &&
1604 		    !qdf_atomic_read(&be_soc->bank_profiles[i].ref_count))
1605 			zero_ref_count_slot = i;
1606 	}
1607 
1608 	if (found_match) {
1609 		temp_str = "matching";
1610 		bank_id = i;
1611 		goto inc_ref_and_return;
1612 	}
1613 	if (unconfigured_slot != DP_BE_INVALID_BANK_ID) {
1614 		temp_str = "unconfigured";
1615 		bank_id = unconfigured_slot;
1616 		goto configure_and_return;
1617 	}
1618 	if (zero_ref_count_slot != DP_BE_INVALID_BANK_ID) {
1619 		temp_str = "zero_ref_count";
1620 		bank_id = zero_ref_count_slot;
1621 	}
1622 	if (bank_id == DP_BE_INVALID_BANK_ID) {
1623 		dp_alert("unable to find TX bank!");
1624 		QDF_BUG(0);
1625 		return bank_id;
1626 	}
1627 
1628 configure_and_return:
1629 	be_soc->bank_profiles[bank_id].is_configured = true;
1630 	be_soc->bank_profiles[bank_id].bank_config.val = vdev_config.val;
1631 	hal_tx_populate_bank_register(be_soc->soc.hal_soc,
1632 				      &be_soc->bank_profiles[bank_id].bank_config,
1633 				      bank_id);
1634 inc_ref_and_return:
1635 	qdf_atomic_inc(&be_soc->bank_profiles[bank_id].ref_count);
1636 	DP_TX_BANK_LOCK_RELEASE(&be_soc->tx_bank_lock);
1637 
1638 	dp_info("found %s slot at index %d, input:0x%x match:0x%x ref_count %u",
1639 		temp_str, bank_id, vdev_config.val,
1640 		be_soc->bank_profiles[bank_id].bank_config.val,
1641 		qdf_atomic_read(&be_soc->bank_profiles[bank_id].ref_count));
1642 
1643 	dp_info("epd:%x encap:%x encryp:%x src_buf_swap:%x link_meta_swap:%x addrx_en:%x addry_en:%x mesh_en:%x vdev_id_check:%x pmac_id:%x mcast_pkt_ctrl:%x",
1644 		be_soc->bank_profiles[bank_id].bank_config.epd,
1645 		be_soc->bank_profiles[bank_id].bank_config.encap_type,
1646 		be_soc->bank_profiles[bank_id].bank_config.encrypt_type,
1647 		be_soc->bank_profiles[bank_id].bank_config.src_buffer_swap,
1648 		be_soc->bank_profiles[bank_id].bank_config.link_meta_swap,
1649 		be_soc->bank_profiles[bank_id].bank_config.addrx_en,
1650 		be_soc->bank_profiles[bank_id].bank_config.addry_en,
1651 		be_soc->bank_profiles[bank_id].bank_config.mesh_enable,
1652 		be_soc->bank_profiles[bank_id].bank_config.vdev_id_check_en,
1653 		be_soc->bank_profiles[bank_id].bank_config.pmac_id,
1654 		be_soc->bank_profiles[bank_id].bank_config.mcast_pkt_ctrl);
1655 
1656 	return bank_id;
1657 }
1658 
dp_tx_put_bank_profile(struct dp_soc_be * be_soc,struct dp_vdev_be * be_vdev)1659 void dp_tx_put_bank_profile(struct dp_soc_be *be_soc,
1660 			    struct dp_vdev_be *be_vdev)
1661 {
1662 	DP_TX_BANK_LOCK_ACQUIRE(&be_soc->tx_bank_lock);
1663 	qdf_atomic_dec(&be_soc->bank_profiles[be_vdev->bank_id].ref_count);
1664 	DP_TX_BANK_LOCK_RELEASE(&be_soc->tx_bank_lock);
1665 }
1666 
dp_tx_update_bank_profile(struct dp_soc_be * be_soc,struct dp_vdev_be * be_vdev)1667 void dp_tx_update_bank_profile(struct dp_soc_be *be_soc,
1668 			       struct dp_vdev_be *be_vdev)
1669 {
1670 	dp_tx_put_bank_profile(be_soc, be_vdev);
1671 	be_vdev->bank_id = dp_tx_get_bank_profile(be_soc, be_vdev);
1672 	be_vdev->vdev.bank_id = be_vdev->bank_id;
1673 }
1674 
dp_tx_desc_pool_init_be(struct dp_soc * soc,uint32_t num_elem,uint8_t pool_id,bool spcl_tx_desc)1675 QDF_STATUS dp_tx_desc_pool_init_be(struct dp_soc *soc,
1676 				   uint32_t num_elem,
1677 				   uint8_t pool_id,
1678 				   bool spcl_tx_desc)
1679 {
1680 	struct dp_tx_desc_pool_s *tx_desc_pool;
1681 	struct dp_hw_cookie_conversion_t *cc_ctx;
1682 	struct dp_spt_page_desc *page_desc;
1683 	struct dp_tx_desc_s *tx_desc;
1684 	uint32_t ppt_idx = 0;
1685 	uint32_t avail_entry_index = 0;
1686 
1687 	if (!num_elem) {
1688 		dp_err("desc_num 0 !!");
1689 		return QDF_STATUS_E_FAILURE;
1690 	}
1691 
1692 	if (spcl_tx_desc) {
1693 		tx_desc_pool = dp_get_spcl_tx_desc_pool(soc, pool_id);
1694 		cc_ctx  = dp_get_spcl_tx_cookie_t(soc, pool_id);
1695 	} else {
1696 		tx_desc_pool = dp_get_tx_desc_pool(soc, pool_id);;
1697 		cc_ctx  = dp_get_tx_cookie_t(soc, pool_id);
1698 	}
1699 	tx_desc = tx_desc_pool->freelist;
1700 	page_desc = &cc_ctx->page_desc_base[0];
1701 	while (tx_desc) {
1702 		if (avail_entry_index == 0) {
1703 			if (ppt_idx >= cc_ctx->total_page_num) {
1704 				dp_alert("insufficient secondary page tables");
1705 				qdf_assert_always(0);
1706 			}
1707 			page_desc = &cc_ctx->page_desc_base[ppt_idx++];
1708 		}
1709 
1710 		/* put each TX Desc VA to SPT pages and
1711 		 * get corresponding ID
1712 		 */
1713 		DP_CC_SPT_PAGE_UPDATE_VA(page_desc->page_v_addr,
1714 					 avail_entry_index,
1715 					 tx_desc);
1716 		tx_desc->id =
1717 			dp_cc_desc_id_generate(page_desc->ppt_index,
1718 					       avail_entry_index);
1719 		tx_desc->pool_id = pool_id;
1720 		dp_tx_desc_set_magic(tx_desc, DP_TX_MAGIC_PATTERN_FREE);
1721 		tx_desc = tx_desc->next;
1722 		avail_entry_index = (avail_entry_index + 1) &
1723 					DP_CC_SPT_PAGE_MAX_ENTRIES_MASK;
1724 	}
1725 
1726 	return QDF_STATUS_SUCCESS;
1727 }
1728 
dp_tx_desc_pool_deinit_be(struct dp_soc * soc,struct dp_tx_desc_pool_s * tx_desc_pool,uint8_t pool_id,bool spcl_tx_desc)1729 void dp_tx_desc_pool_deinit_be(struct dp_soc *soc,
1730 			       struct dp_tx_desc_pool_s *tx_desc_pool,
1731 			       uint8_t pool_id, bool spcl_tx_desc)
1732 {
1733 	struct dp_spt_page_desc *page_desc;
1734 	int i = 0;
1735 	struct dp_hw_cookie_conversion_t *cc_ctx;
1736 
1737 	if (spcl_tx_desc)
1738 		cc_ctx  = dp_get_spcl_tx_cookie_t(soc, pool_id);
1739 	else
1740 		cc_ctx  = dp_get_tx_cookie_t(soc, pool_id);
1741 
1742 	for (i = 0; i < cc_ctx->total_page_num; i++) {
1743 		page_desc = &cc_ctx->page_desc_base[i];
1744 		qdf_mem_zero(page_desc->page_v_addr, qdf_page_size);
1745 	}
1746 }
1747 
1748 #ifdef WLAN_FEATURE_NEAR_FULL_IRQ
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)1749 uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
1750 			       hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
1751 			       uint32_t quota)
1752 {
1753 	struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id];
1754 	uint32_t work_done = 0;
1755 
1756 	if (dp_srng_get_near_full_level(soc, tx_comp_ring) <
1757 			DP_SRNG_THRESH_NEAR_FULL)
1758 		return 0;
1759 
1760 	qdf_atomic_set(&tx_comp_ring->near_full, 1);
1761 	work_done++;
1762 
1763 	return work_done;
1764 }
1765 #endif
1766 
1767 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
1768 	defined(WLAN_CONFIG_TX_DELAY)
1769 #define PPDUID_GET_HW_LINK_ID(PPDU_ID, LINK_ID_OFFSET, LINK_ID_BITS) \
1770 	(((PPDU_ID) >> (LINK_ID_OFFSET)) & ((1 << (LINK_ID_BITS)) - 1))
1771 
1772 #define HW_TX_DELAY_MAX                       0x1000000
1773 #define TX_COMPL_SHIFT_BUFFER_TIMESTAMP_US    10
1774 #define HW_TX_DELAY_MASK                      0x1FFFFFFF
1775 #define TX_COMPL_BUFFER_TSTAMP_US(TSTAMP) \
1776 	(((TSTAMP) << TX_COMPL_SHIFT_BUFFER_TIMESTAMP_US) & \
1777 	 HW_TX_DELAY_MASK)
1778 
1779 static inline
dp_mlo_compute_hw_delay_us(struct dp_soc * soc,struct dp_vdev * vdev,struct hal_tx_completion_status * ts,uint32_t * delay_us)1780 QDF_STATUS dp_mlo_compute_hw_delay_us(struct dp_soc *soc,
1781 				      struct dp_vdev *vdev,
1782 				      struct hal_tx_completion_status *ts,
1783 				      uint32_t *delay_us)
1784 {
1785 	uint32_t ppdu_id;
1786 	uint8_t link_id_offset, link_id_bits;
1787 	uint8_t hw_link_id;
1788 	uint32_t msdu_tqm_enqueue_tstamp_us, final_msdu_tqm_enqueue_tstamp_us;
1789 	uint32_t msdu_compl_tsf_tstamp_us, final_msdu_compl_tsf_tstamp_us;
1790 	uint32_t delay;
1791 	int32_t delta_tsf2, delta_tqm;
1792 
1793 	if (!ts->valid)
1794 		return QDF_STATUS_E_INVAL;
1795 
1796 	link_id_offset = soc->link_id_offset;
1797 	link_id_bits = soc->link_id_bits;
1798 	ppdu_id = ts->ppdu_id;
1799 	hw_link_id = PPDUID_GET_HW_LINK_ID(ppdu_id, link_id_offset,
1800 					   link_id_bits);
1801 
1802 	msdu_tqm_enqueue_tstamp_us =
1803 		TX_COMPL_BUFFER_TSTAMP_US(ts->buffer_timestamp);
1804 	msdu_compl_tsf_tstamp_us = ts->tsf;
1805 
1806 	delta_tsf2 = dp_mlo_get_delta_tsf2_wrt_mlo_offset(soc, hw_link_id);
1807 	delta_tqm = dp_mlo_get_delta_tqm_wrt_mlo_offset(soc);
1808 
1809 	final_msdu_tqm_enqueue_tstamp_us = (msdu_tqm_enqueue_tstamp_us +
1810 			delta_tqm) & HW_TX_DELAY_MASK;
1811 
1812 	final_msdu_compl_tsf_tstamp_us = (msdu_compl_tsf_tstamp_us +
1813 			delta_tsf2) & HW_TX_DELAY_MASK;
1814 
1815 	delay = (final_msdu_compl_tsf_tstamp_us -
1816 		final_msdu_tqm_enqueue_tstamp_us) & HW_TX_DELAY_MASK;
1817 
1818 	if (delay > HW_TX_DELAY_MAX)
1819 		return QDF_STATUS_E_FAILURE;
1820 
1821 	if (delay_us)
1822 		*delay_us = delay;
1823 
1824 	return QDF_STATUS_SUCCESS;
1825 }
1826 #else
1827 static inline
dp_mlo_compute_hw_delay_us(struct dp_soc * soc,struct dp_vdev * vdev,struct hal_tx_completion_status * ts,uint32_t * delay_us)1828 QDF_STATUS dp_mlo_compute_hw_delay_us(struct dp_soc *soc,
1829 				      struct dp_vdev *vdev,
1830 				      struct hal_tx_completion_status *ts,
1831 				      uint32_t *delay_us)
1832 {
1833 	return QDF_STATUS_SUCCESS;
1834 }
1835 #endif
1836 
dp_tx_compute_tx_delay_be(struct dp_soc * soc,struct dp_vdev * vdev,struct hal_tx_completion_status * ts,uint32_t * delay_us)1837 QDF_STATUS dp_tx_compute_tx_delay_be(struct dp_soc *soc,
1838 				     struct dp_vdev *vdev,
1839 				     struct hal_tx_completion_status *ts,
1840 				     uint32_t *delay_us)
1841 {
1842 	return dp_mlo_compute_hw_delay_us(soc, vdev, ts, delay_us);
1843 }
1844 
1845 static inline
dp_tx_nbuf_map_be(struct dp_vdev * vdev,struct dp_tx_desc_s * tx_desc,qdf_nbuf_t nbuf)1846 qdf_dma_addr_t dp_tx_nbuf_map_be(struct dp_vdev *vdev,
1847 				 struct dp_tx_desc_s *tx_desc,
1848 				 qdf_nbuf_t nbuf)
1849 {
1850 	qdf_nbuf_dma_clean_range_no_dsb((void *)nbuf->data,
1851 					(void *)(nbuf->data + 256));
1852 
1853 	return (qdf_dma_addr_t)qdf_mem_virt_to_phys(nbuf->data);
1854 }
1855 
1856 static inline
dp_tx_nbuf_unmap_be(struct dp_soc * soc,struct dp_tx_desc_s * desc)1857 void dp_tx_nbuf_unmap_be(struct dp_soc *soc,
1858 			 struct dp_tx_desc_s *desc)
1859 {
1860 }
1861 
1862 #ifdef QCA_DP_TX_NBUF_LIST_FREE
dp_tx_fast_send_be(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,qdf_nbuf_t nbuf)1863 qdf_nbuf_t dp_tx_fast_send_be(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
1864 			      qdf_nbuf_t nbuf)
1865 {
1866 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
1867 	struct dp_vdev *vdev = NULL;
1868 	struct dp_pdev *pdev = NULL;
1869 	struct dp_tx_desc_s *tx_desc;
1870 	uint16_t desc_pool_id;
1871 	uint16_t pkt_len;
1872 	qdf_dma_addr_t paddr;
1873 	QDF_STATUS status = QDF_STATUS_E_RESOURCES;
1874 	uint8_t cached_desc[HAL_TX_DESC_LEN_BYTES] = { 0 };
1875 	hal_ring_handle_t hal_ring_hdl = NULL;
1876 	uint32_t *hal_tx_desc_cached;
1877 	void *hal_tx_desc;
1878 	uint8_t tid = HTT_TX_EXT_TID_INVALID;
1879 	uint8_t xmit_type = qdf_nbuf_get_vdev_xmit_type(nbuf);
1880 	uint8_t sawf_tid = HTT_TX_EXT_TID_INVALID;
1881 
1882 	if (qdf_unlikely(vdev_id >= MAX_VDEV_CNT))
1883 		return nbuf;
1884 
1885 	vdev = soc->vdev_id_map[vdev_id];
1886 	if (qdf_unlikely(!vdev))
1887 		return nbuf;
1888 
1889 	desc_pool_id = qdf_nbuf_get_queue_mapping(nbuf) & DP_TX_QUEUE_MASK;
1890 
1891 	pkt_len = qdf_nbuf_headlen(nbuf);
1892 	DP_STATS_INC_PKT(vdev, tx_i[xmit_type].rcvd, 1, pkt_len);
1893 	DP_STATS_INC(vdev, tx_i[xmit_type].rcvd_in_fast_xmit_flow, 1);
1894 	DP_STATS_INC(vdev, tx_i[xmit_type].rcvd_per_core[desc_pool_id], 1);
1895 
1896 	pdev = vdev->pdev;
1897 	if (dp_tx_limit_check(vdev, nbuf))
1898 		return nbuf;
1899 
1900 	if (qdf_unlikely(vdev->skip_sw_tid_classification
1901 				& DP_TXRX_HLOS_TID_OVERRIDE_ENABLED)) {
1902 		tid = qdf_nbuf_get_priority(nbuf);
1903 
1904 		if (tid >= DP_TX_INVALID_QOS_TAG)
1905 			tid = HTT_TX_EXT_TID_INVALID;
1906 	}
1907 
1908 	tx_desc = dp_tx_desc_alloc(soc, desc_pool_id);
1909 
1910 	if (qdf_unlikely(!tx_desc)) {
1911 		DP_STATS_INC(vdev, tx_i[xmit_type].dropped.desc_na.num, 1);
1912 		DP_STATS_INC(vdev,
1913 			     tx_i[xmit_type].dropped.desc_na_exc_alloc_fail.num,
1914 			     1);
1915 		return nbuf;
1916 	}
1917 
1918 	dp_tx_outstanding_inc(pdev);
1919 
1920 	/* Initialize the SW tx descriptor */
1921 	tx_desc->nbuf = nbuf;
1922 	tx_desc->frm_type = dp_tx_frm_std;
1923 	tx_desc->tx_encap_type = vdev->tx_encap_type;
1924 	tx_desc->vdev_id = vdev_id;
1925 	tx_desc->pdev = pdev;
1926 	tx_desc->pkt_offset = 0;
1927 	tx_desc->length = pkt_len;
1928 	tx_desc->flags |= pdev->tx_fast_flag;
1929 
1930 	tx_desc->nbuf->fast_recycled = 1;
1931 
1932 	if (nbuf->is_from_recycler && nbuf->fast_xmit)
1933 		tx_desc->flags |= DP_TX_DESC_FLAG_FAST;
1934 
1935 	paddr =  dp_tx_nbuf_map_be(vdev, tx_desc, nbuf);
1936 	if (!paddr) {
1937 		/* Handle failure */
1938 		dp_err("qdf_nbuf_map failed");
1939 		DP_STATS_INC(vdev, tx_i[xmit_type].dropped.dma_error, 1);
1940 		goto release_desc;
1941 	}
1942 
1943 	tx_desc->dma_addr = paddr;
1944 
1945 	hal_tx_desc_cached = (void *)cached_desc;
1946 	hal_tx_desc_cached[0] = (uint32_t)tx_desc->dma_addr;
1947 	hal_tx_desc_cached[1] = tx_desc->id <<
1948 		TCL_DATA_CMD_BUF_ADDR_INFO_SW_BUFFER_COOKIE_LSB;
1949 
1950 	/* bank_id */
1951 	hal_tx_desc_cached[2] = vdev->bank_id << TCL_DATA_CMD_BANK_ID_LSB;
1952 	hal_tx_desc_cached[3] = vdev->htt_tcl_metadata <<
1953 		TCL_DATA_CMD_TCL_CMD_NUMBER_LSB;
1954 
1955 	hal_tx_desc_cached[4] = tx_desc->length;
1956 	/* l3 and l4 checksum enable */
1957 	hal_tx_desc_cached[4] |= DP_TX_L3_L4_CSUM_ENABLE <<
1958 		TCL_DATA_CMD_IPV4_CHECKSUM_EN_LSB;
1959 
1960 	hal_tx_desc_cached[5] = vdev->lmac_id << TCL_DATA_CMD_PMAC_ID_LSB;
1961 	hal_tx_desc_cached[5] |= vdev->vdev_id << TCL_DATA_CMD_VDEV_ID_LSB;
1962 
1963 	if (qdf_unlikely(dp_sawf_tag_valid_get(nbuf))) {
1964 		sawf_tid = dp_sawf_config_be(soc, hal_tx_desc_cached,
1965 					     NULL, nbuf, NULL);
1966 		if (sawf_tid != HTT_TX_EXT_TID_INVALID)
1967 			tid = sawf_tid;
1968 	}
1969 
1970 	if (tid != HTT_TX_EXT_TID_INVALID) {
1971 		hal_tx_desc_cached[5] |= tid << TCL_DATA_CMD_HLOS_TID_LSB;
1972 		hal_tx_desc_cached[5] |= 1 << TCL_DATA_CMD_HLOS_TID_OVERWRITE_LSB;
1973 	}
1974 
1975 	if (vdev->opmode == wlan_op_mode_sta)
1976 		hal_tx_desc_cached[6] = vdev->bss_ast_idx |
1977 			((vdev->bss_ast_hash & 0xF) <<
1978 			 TCL_DATA_CMD_CACHE_SET_NUM_LSB);
1979 
1980 	hal_ring_hdl = dp_tx_get_hal_ring_hdl(soc, desc_pool_id);
1981 
1982 	if (qdf_unlikely(dp_tx_hal_ring_access_start(soc, hal_ring_hdl))) {
1983 		dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
1984 		DP_STATS_INC(soc, tx.tcl_ring_full[desc_pool_id], 1);
1985 		DP_STATS_INC(vdev, tx_i[xmit_type].dropped.enqueue_fail, 1);
1986 		goto ring_access_fail2;
1987 	}
1988 
1989 	hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_ring_hdl);
1990 	if (qdf_unlikely(!hal_tx_desc)) {
1991 		dp_verbose_debug("TCL ring full ring_id:%d", desc_pool_id);
1992 		DP_STATS_INC(soc, tx.tcl_ring_full[desc_pool_id], 1);
1993 		DP_STATS_INC(vdev, tx_i[xmit_type].dropped.enqueue_fail, 1);
1994 		goto ring_access_fail;
1995 	}
1996 
1997 	tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
1998 
1999 	/* Sync cached descriptor with HW */
2000 	qdf_mem_copy(hal_tx_desc, hal_tx_desc_cached, DP_TX_FAST_DESC_SIZE);
2001 	qdf_dsb();
2002 
2003 	DP_STATS_INC_PKT(vdev, tx_i[xmit_type].processed, 1, tx_desc->length);
2004 	DP_STATS_INC(soc, tx.tcl_enq[desc_pool_id], 1);
2005 	status = QDF_STATUS_SUCCESS;
2006 
2007 ring_access_fail:
2008 	dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl, 0);
2009 
2010 ring_access_fail2:
2011 	if (status != QDF_STATUS_SUCCESS) {
2012 		dp_tx_nbuf_unmap_be(soc, tx_desc);
2013 		goto release_desc;
2014 	}
2015 
2016 	return NULL;
2017 
2018 release_desc:
2019 	dp_tx_desc_release(soc, tx_desc, desc_pool_id);
2020 
2021 	return nbuf;
2022 }
2023 #endif
2024 
dp_tx_desc_pool_alloc_be(struct dp_soc * soc,uint32_t num_elem,uint8_t pool_id)2025 QDF_STATUS dp_tx_desc_pool_alloc_be(struct dp_soc *soc, uint32_t num_elem,
2026 				    uint8_t pool_id)
2027 {
2028 	return QDF_STATUS_SUCCESS;
2029 }
2030 
dp_tx_desc_pool_free_be(struct dp_soc * soc,uint8_t pool_id)2031 void dp_tx_desc_pool_free_be(struct dp_soc *soc, uint8_t pool_id)
2032 {
2033 }
2034