1 /*
2  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 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 #if !defined(__WLAN_DP_RX_THREAD_H)
21 #define __WLAN_DP_RX_THREAD_H
22 
23 #include <qdf_lock.h>
24 #include <qdf_event.h>
25 #include <qdf_threads.h>
26 #include <wlan_objmgr_vdev_obj.h>
27 #include "cfg_dp.h"
28 #include <cdp_txrx_cmn_struct.h>
29 #include <cdp_txrx_cmn.h>
30 #include "wlan_cfg.h"
31 #include "qdf_nbuf.h"
32 #include "qdf_threads.h"
33 #include "qdf_net_if.h"
34 
35 /* Maximum number of REO rings supported (for stats tracking) */
36 #define DP_RX_TM_MAX_REO_RINGS WLAN_CFG_NUM_REO_DEST_RING
37 /* Number of DP RX threads supported */
38 #define DP_MAX_RX_THREADS WLAN_CFG_NUM_REO_DEST_RING
39 
40 /*
41  * struct dp_rx_tm_handle_cmn - Opaque handle for rx_threads to store
42  * rx_tm_handle. This handle will be common for all the threads.
43  * Individual threads should not be accessing
44  * elements from dp_rx_tm_handle. It should be via an API.
45  */
46 struct dp_rx_tm_handle_cmn;
47 
48 /**
49  * struct dp_rx_thread_stats - structure holding stats for DP RX thread
50  * @nbuf_queued: packets queued into the thread per reo ring
51  * @nbuf_queued_total: packets queued into the thread for all reo rings
52  * @nbuf_dequeued: packets de-queued from the thread
53  * @nbuf_sent_to_stack: packets sent to the stack. some dequeued packets may be
54  *			dropped due to no peer or vdev, hence this stat.
55  * @gro_flushes: number of GRO flushes
56  * @gro_flushes_by_vdev_del: number of GRO flushes triggered by vdev del.
57  * @nbufq_max_len: maximum number of nbuf_lists queued for the thread
58  * @dropped_invalid_vdev: packets(nbuf_list) dropped due to no vdev
59  * @rx_flushed: packets flushed after vdev delete
60  * @dropped_invalid_peer: packets(nbuf_list) dropped due to no peer
61  * @dropped_invalid_os_rx_handles: packets(nbuf_list) dropped due to no os rx
62  * handles
63  * @dropped_others: packets dropped due to other reasons
64  * @dropped_enq_fail: packets dropped due to pending queue full
65  * @rx_nbufq_loop_yield: rx loop yield counter
66  */
67 struct dp_rx_thread_stats {
68 	unsigned int nbuf_queued[DP_RX_TM_MAX_REO_RINGS];
69 	unsigned int nbuf_queued_total;
70 	unsigned int nbuf_dequeued;
71 	unsigned int nbuf_sent_to_stack;
72 	unsigned int gro_flushes;
73 	unsigned int gro_flushes_by_vdev_del;
74 	unsigned int nbufq_max_len;
75 	unsigned int dropped_invalid_vdev;
76 	unsigned int rx_flushed;
77 	unsigned int dropped_invalid_peer;
78 	unsigned int dropped_invalid_os_rx_handles;
79 	unsigned int dropped_others;
80 	unsigned int dropped_enq_fail;
81 	unsigned int rx_nbufq_loop_yield;
82 };
83 
84 /**
85  * enum dp_rx_refill_thread_state - enum to keep track of rx refill thread state
86  * @DP_RX_REFILL_THREAD_INVALID: initial invalid state
87  * @DP_RX_REFILL_THREAD_RUNNING: rx refill thread functional(NOT suspended,
88  *                      processing packets or waiting on a wait_queue)
89  * @DP_RX_REFILL_THREAD_SUSPENDING: rx refill thread is suspending
90  * @DP_RX_REFILL_THREAD_SUSPENDED: rx refill_thread suspended
91  */
92 enum dp_rx_refill_thread_state {
93 	DP_RX_REFILL_THREAD_INVALID,
94 	DP_RX_REFILL_THREAD_RUNNING,
95 	DP_RX_REFILL_THREAD_SUSPENDING,
96 	DP_RX_REFILL_THREAD_SUSPENDED
97 };
98 
99 /**
100  * struct dp_rx_thread - structure holding variables for a single DP RX thread
101  * @id: id of the dp_rx_thread (0 or 1 or 2..DP_MAX_RX_THREADS - 1)
102  * @task: task structure corresponding to the thread
103  * @start_event: handle of Event for DP Rx thread to signal startup
104  * @suspend_event: handle of Event for DP Rx thread to signal suspend
105  * @resume_event: handle of Event for DP Rx thread to signal resume
106  * @shutdown_event: handle of Event for DP Rx thread to signal shutdown
107  * @vdev_del_event: handle of Event for vdev del thread to signal completion
108  *		    for gro flush
109  * @gro_flush_ind: gro flush indication for DP Rx thread
110  * @event_flag: event flag to post events to DP Rx thread
111  * @nbuf_queue:nbuf queue used to store RX packets
112  * @nbufq_len: length of the nbuf queue
113  * @aff_mask: cuurent affinity mask of the DP Rx thread
114  * @stats: per thread stats
115  * @rtm_handle_cmn: abstract RX TM handle. This allows access to the dp_rx_tm
116  *		    structures via APIs.
117  * @napi: napi to deliver packet to stack via GRO
118  * @wait_q: wait queue to conditionally wait on events for DP Rx thread
119  * @netdev: dummy netdev to initialize the napi structure with
120  */
121 struct dp_rx_thread {
122 	uint8_t id;
123 	qdf_thread_t *task;
124 	qdf_event_t start_event;
125 	qdf_event_t suspend_event;
126 	qdf_event_t resume_event;
127 	qdf_event_t shutdown_event;
128 	qdf_event_t vdev_del_event;
129 	qdf_atomic_t gro_flush_ind;
130 	unsigned long event_flag;
131 	qdf_nbuf_queue_head_t nbuf_queue;
132 	unsigned long aff_mask;
133 	struct dp_rx_thread_stats stats;
134 	struct dp_rx_tm_handle_cmn *rtm_handle_cmn;
135 	qdf_napi_struct napi;
136 	qdf_wait_queue_head_t wait_q;
137 	qdf_dummy_netdev_t netdev;
138 };
139 
140 /**
141  * struct dp_rx_refill_thread - structure holding info of DP Rx refill thread
142  * @task: task structure corresponding to the thread
143  * @start_event: handle of Event for DP Rx refill thread to signal startup
144  * @suspend_event: handle of Event for DP Rx refill thread to signal suspend
145  * @resume_event: handle of Event for DP Rx refill thread to signal resume
146  * @shutdown_event: handle of Event for DP Rx refill thread to signal shutdown
147  * @event_flag: event flag to post events to DP Rx refill thread
148  * @wait_q: wait queue to conditionally wait on events for DP Rx refill thread
149  * @enabled: flag to check whether DP Rx refill thread is enabled
150  * @soc: abstract DP soc reference used in internal API's
151  * @state: state of DP Rx refill thread
152  */
153 struct dp_rx_refill_thread {
154 	qdf_thread_t *task;
155 	qdf_event_t start_event;
156 	qdf_event_t suspend_event;
157 	qdf_event_t resume_event;
158 	qdf_event_t shutdown_event;
159 	unsigned long event_flag;
160 	qdf_wait_queue_head_t wait_q;
161 	bool enabled;
162 	void *soc;
163 	enum dp_rx_refill_thread_state state;
164 };
165 
166 /**
167  * enum dp_rx_thread_state - enum to keep track of the state of the rx threads
168  * @DP_RX_THREADS_INVALID: initial invalid state
169  * @DP_RX_THREADS_RUNNING: rx threads functional(NOT suspended, processing
170  *			  packets or waiting on a wait_queue)
171  * @DP_RX_THREADS_SUSPENDING: rx thread is suspending
172  * @DP_RX_THREADS_SUSPENDED: rx_threads suspended from cfg8011 suspend
173  */
174 enum dp_rx_thread_state {
175 	DP_RX_THREADS_INVALID,
176 	DP_RX_THREADS_RUNNING,
177 	DP_RX_THREADS_SUSPENDING,
178 	DP_RX_THREADS_SUSPENDED
179 };
180 
181 /**
182  * struct dp_rx_tm_handle - DP RX thread infrastructure handle
183  * @num_dp_rx_threads: number of DP RX threads initialized
184  * @txrx_handle_cmn: opaque txrx handle to get to pdev and soc
185  * @state: state of the rx_threads. All of them should be in the same state.
186  * @rx_thread: array of pointers of type struct dp_rx_thread
187  * @allow_dropping: flag to indicate frame dropping is enabled
188  */
189 struct dp_rx_tm_handle {
190 	uint8_t num_dp_rx_threads;
191 	struct dp_txrx_handle_cmn *txrx_handle_cmn;
192 	enum dp_rx_thread_state state;
193 	struct dp_rx_thread **rx_thread;
194 	qdf_atomic_t allow_dropping;
195 };
196 
197 /**
198  * enum dp_rx_gro_flush_code - enum differentiate different GRO flushes
199  * @DP_RX_GRO_NOT_FLUSH: not fush indication
200  * @DP_RX_GRO_NORMAL_FLUSH: Regular full flush
201  * @DP_RX_GRO_LOW_TPUT_FLUSH: Flush during low tput level
202  */
203 enum dp_rx_gro_flush_code {
204 	DP_RX_GRO_NOT_FLUSH = 0,
205 	DP_RX_GRO_NORMAL_FLUSH,
206 	DP_RX_GRO_LOW_TPUT_FLUSH
207 };
208 
209 /**
210  * struct dp_txrx_config - dp txrx configuration passed to dp txrx modules
211  * @enable_rx_threads: DP rx threads or not
212  */
213 struct dp_txrx_config {
214 	bool enable_rx_threads;
215 };
216 
217 struct dp_txrx_handle_cmn;
218 
219 /**
220  * struct dp_txrx_handle - main dp txrx container handle
221  * @pdev: cdp_pdev pdev handle
222  * @soc: ol_txrx_soc_handle soc handle
223  * @refill_thread: rx refill thread infra handle
224  * @rx_tm_hdl: rx thread infrastructure handle
225  * @config: configuration for DP TXRX modules
226  */
227 struct dp_txrx_handle {
228 	ol_txrx_soc_handle soc;
229 	struct cdp_pdev *pdev;
230 	struct dp_rx_tm_handle rx_tm_hdl;
231 	struct dp_rx_refill_thread refill_thread;
232 	struct dp_txrx_config config;
233 };
234 
235 /**
236  * dp_rx_refill_thread_init() - Initialize DP Rx refill threads
237  * @refill_thread: Contains over all rx refill thread info
238  *
239  * Return: QDF_STATUS
240  */
241 QDF_STATUS dp_rx_refill_thread_init(struct dp_rx_refill_thread *refill_thread);
242 
243 /**
244  * dp_rx_refill_thread_deinit() - De-initialize DP Rx refill threads
245  * @refill_thread: Contains over all rx refill thread info
246  *
247  * Return: QDF_STATUS
248  */
249 QDF_STATUS
250 dp_rx_refill_thread_deinit(struct dp_rx_refill_thread *refill_thread);
251 
252 /**
253  * dp_rx_tm_init() - initialize DP Rx thread infrastructure
254  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
255  * @num_dp_rx_threads: number of DP Rx threads to be initialized
256  *
257  * Return: QDF_STATUS_SUCCESS
258  */
259 QDF_STATUS dp_rx_tm_init(struct dp_rx_tm_handle *rx_tm_hdl,
260 			 uint8_t num_dp_rx_threads);
261 
262 /**
263  * dp_rx_tm_deinit() - de-initialize DP Rx thread infrastructure
264  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
265  *
266  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
267  */
268 QDF_STATUS dp_rx_tm_deinit(struct dp_rx_tm_handle *rx_tm_hdl);
269 
270 /**
271  * dp_rx_tm_enqueue_pkt() - enqueue RX packet into RXTI
272  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread infrastructure
273  * @nbuf_list: single or a list of nbufs to be enqueued into RXTI
274  *
275  * Return: QDF_STATUS_SUCCESS
276  */
277 QDF_STATUS dp_rx_tm_enqueue_pkt(struct dp_rx_tm_handle *rx_tm_hdl,
278 				qdf_nbuf_t nbuf_list);
279 
280 /**
281  * dp_rx_tm_gro_flush_ind() - flush GRO packets for a RX Context Id
282  * @rx_tm_handle: dp_rx_tm_handle containing the overall thread infrastructure
283  * @rx_ctx_id: RX Thread Context Id for which GRO flush needs to be done
284  * @flush_code: flush code to differentiate low TPUT flush
285  *
286  * Return: QDF_STATUS_SUCCESS
287  */
288 QDF_STATUS dp_rx_tm_gro_flush_ind(struct dp_rx_tm_handle *rx_tm_handle,
289 				  int rx_ctx_id,
290 				  enum dp_rx_gro_flush_code flush_code);
291 /**
292  * dp_rx_refill_thread_suspend() - Suspend RX refill thread
293  * @refill_thread: pointer to dp_rx_refill_thread object
294  *
295  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
296  */
297 QDF_STATUS
298 dp_rx_refill_thread_suspend(struct dp_rx_refill_thread *refill_thread);
299 
300 /**
301  * dp_rx_tm_suspend() - suspend all threads in RXTI
302  * @rx_tm_handle: pointer to dp_rx_tm_handle object
303  *
304  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
305  */
306 QDF_STATUS dp_rx_tm_suspend(struct dp_rx_tm_handle *rx_tm_handle);
307 
308 /**
309  * dp_rx_tm_flush_by_vdev_id() - flush rx packets by vdev_id in all
310  * rx thread queues
311  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
312  *             infrastructure
313  * @vdev_id: vdev id for which packets are to be flushed
314  *
315  * Return: QDF_STATUS_SUCCESS
316  */
317 QDF_STATUS dp_rx_tm_flush_by_vdev_id(struct dp_rx_tm_handle *rx_tm_hdl,
318 				     uint8_t vdev_id);
319 
320 /**
321  * dp_rx_refill_thread_resume() - Resume RX refill thread
322  * @refill_thread: pointer to dp_rx_refill_thread
323  *
324  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
325  */
326 QDF_STATUS
327 dp_rx_refill_thread_resume(struct dp_rx_refill_thread *refill_thread);
328 
329 /**
330  * dp_rx_tm_resume() - resume all threads in RXTI
331  * @rx_tm_handle: pointer to dp_rx_tm_handle object
332  *
333  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
334  */
335 QDF_STATUS dp_rx_tm_resume(struct dp_rx_tm_handle *rx_tm_handle);
336 
337 /**
338  * dp_rx_tm_dump_stats() - dump stats for all threads in RXTI
339  * @rx_tm_handle: pointer to dp_rx_tm_handle object
340  *
341  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
342  */
343 QDF_STATUS dp_rx_tm_dump_stats(struct dp_rx_tm_handle *rx_tm_handle);
344 
345 /**
346  * dp_rx_thread_get_txrx_handle() - get txrx handle from rx_tm_handle_cmn
347  * @rx_tm_handle_cmn: opaque pointer to dp_rx_tm_handle_cmn struct
348  *
349  * Return: pointer to dp_txrx_handle_cmn handle
350  */
351 static inline struct dp_txrx_handle_cmn*
dp_rx_thread_get_txrx_handle(struct dp_rx_tm_handle_cmn * rx_tm_handle_cmn)352 dp_rx_thread_get_txrx_handle(struct dp_rx_tm_handle_cmn *rx_tm_handle_cmn)
353 {
354 	return (((struct dp_rx_tm_handle *)rx_tm_handle_cmn)->txrx_handle_cmn);
355 }
356 
357 /**
358  * dp_rx_tm_get_napi_context() - get NAPI context for a RX CTX ID
359  * @rx_ctx_id: RX context ID (RX thread ID) corresponding to which NAPI is
360  *             needed
361  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
362  *             infrastructure
363  *
364  * Return: NULL on failure, else pointer to NAPI corresponding to rx_ctx_id
365  */
366 qdf_napi_struct *dp_rx_tm_get_napi_context(struct dp_rx_tm_handle *rx_tm_hdl,
367 					   uint8_t rx_ctx_id);
368 
369 /**
370  * dp_rx_tm_set_cpu_mask() - set CPU mask for RX threads
371  * @rx_tm_hdl: dp_rx_tm_handle containing the overall thread
372  *             infrastructure
373  * @new_mask: New CPU mask pointer
374  *
375  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
376  */
377 QDF_STATUS dp_rx_tm_set_cpu_mask(struct dp_rx_tm_handle *rx_tm_hdl,
378 				 qdf_cpu_mask *new_mask);
379 
380 #ifdef FEATURE_WLAN_DP_RX_THREADS
381 /**
382  * dp_txrx_get_cmn_hdl_frm_ext_hdl() - conversion func ext_hdl->txrx_handle_cmn
383  * @dp_ext_hdl: pointer to dp_txrx_handle structure
384  *
385  * Return: typecasted pointer of type - struct dp_txrx_handle_cmn
386  */
387 static inline struct dp_txrx_handle_cmn *
dp_txrx_get_cmn_hdl_frm_ext_hdl(struct dp_txrx_handle * dp_ext_hdl)388 dp_txrx_get_cmn_hdl_frm_ext_hdl(struct dp_txrx_handle *dp_ext_hdl)
389 {
390 	return (struct dp_txrx_handle_cmn *)dp_ext_hdl;
391 }
392 
393 /**
394  * dp_txrx_get_ext_hdl_frm_cmn_hdl() - conversion func txrx_handle_cmn->ext_hdl
395  * @txrx_cmn_hdl: pointer to dp_txrx_handle_cmn structure
396  *
397  * Return: typecasted pointer of type - struct dp_txrx_handle
398  */
399 static inline struct dp_txrx_handle *
dp_txrx_get_ext_hdl_frm_cmn_hdl(struct dp_txrx_handle_cmn * txrx_cmn_hdl)400 dp_txrx_get_ext_hdl_frm_cmn_hdl(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
401 {
402 	return (struct dp_txrx_handle *)txrx_cmn_hdl;
403 }
404 
405 static inline ol_txrx_soc_handle
dp_txrx_get_soc_from_ext_handle(struct dp_txrx_handle_cmn * txrx_cmn_hdl)406 dp_txrx_get_soc_from_ext_handle(struct dp_txrx_handle_cmn *txrx_cmn_hdl)
407 {
408 	struct dp_txrx_handle *dp_ext_hdl;
409 
410 	dp_ext_hdl = dp_txrx_get_ext_hdl_frm_cmn_hdl(txrx_cmn_hdl);
411 
412 	return dp_ext_hdl->soc;
413 }
414 
415 /**
416  * dp_txrx_init() - initialize DP TXRX module
417  * @soc: ol_txrx_soc_handle
418  * @pdev_id: id of dp pdev handle
419  * @config: configuration for DP TXRX modules
420  *
421  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
422  */
423 QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id,
424 			struct dp_txrx_config *config);
425 
426 /**
427  * dp_txrx_deinit() - de-initialize DP TXRX module
428  * @soc: ol_txrx_soc_handle
429  *
430  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
431  */
432 QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc);
433 
434 /**
435  * dp_txrx_flush_pkts_by_vdev_id() - flush rx packets for a vdev_id
436  * @soc: ol_txrx_soc_handle object
437  * @vdev_id: vdev_id for which rx packets are to be flushed
438  *
439  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
440  */
dp_txrx_flush_pkts_by_vdev_id(ol_txrx_soc_handle soc,uint8_t vdev_id)441 static inline QDF_STATUS dp_txrx_flush_pkts_by_vdev_id(ol_txrx_soc_handle soc,
442 						       uint8_t vdev_id)
443 {
444 	struct dp_txrx_handle *dp_ext_hdl;
445 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
446 
447 	if (!soc) {
448 		qdf_status = QDF_STATUS_E_INVAL;
449 		goto ret;
450 	}
451 
452 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
453 	if (!dp_ext_hdl) {
454 		qdf_status = QDF_STATUS_E_FAULT;
455 		goto ret;
456 	}
457 
458 	qdf_status = dp_rx_tm_flush_by_vdev_id(&dp_ext_hdl->rx_tm_hdl, vdev_id);
459 ret:
460 	return qdf_status;
461 }
462 
463 /**
464  * dp_txrx_resume() - resume all threads
465  * @soc: ol_txrx_soc_handle object
466  *
467  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
468  */
dp_txrx_resume(ol_txrx_soc_handle soc)469 static inline QDF_STATUS dp_txrx_resume(ol_txrx_soc_handle soc)
470 {
471 	struct dp_txrx_handle *dp_ext_hdl;
472 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
473 	struct dp_rx_refill_thread *refill_thread;
474 
475 	if (!soc) {
476 		qdf_status = QDF_STATUS_E_INVAL;
477 		goto ret;
478 	}
479 
480 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
481 	if (!dp_ext_hdl) {
482 		qdf_status = QDF_STATUS_E_FAULT;
483 		goto ret;
484 	}
485 
486 	refill_thread = &dp_ext_hdl->refill_thread;
487 	if (refill_thread->enabled) {
488 		qdf_status = dp_rx_refill_thread_resume(refill_thread);
489 		if (qdf_status != QDF_STATUS_SUCCESS)
490 			return qdf_status;
491 	}
492 
493 	qdf_status = dp_rx_tm_resume(&dp_ext_hdl->rx_tm_hdl);
494 ret:
495 	return qdf_status;
496 }
497 
498 /**
499  * dp_txrx_suspend() - suspend all threads
500  * @soc: ol_txrx_soc_handle object
501  *
502  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
503  */
dp_txrx_suspend(ol_txrx_soc_handle soc)504 static inline QDF_STATUS dp_txrx_suspend(ol_txrx_soc_handle soc)
505 {
506 	struct dp_txrx_handle *dp_ext_hdl;
507 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
508 	struct dp_rx_refill_thread *refill_thread;
509 
510 	if (!soc) {
511 		qdf_status = QDF_STATUS_E_INVAL;
512 		goto ret;
513 	}
514 
515 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
516 	if (!dp_ext_hdl) {
517 		qdf_status = QDF_STATUS_E_FAULT;
518 		goto ret;
519 	}
520 
521 	refill_thread = &dp_ext_hdl->refill_thread;
522 	if (refill_thread->enabled) {
523 		qdf_status = dp_rx_refill_thread_suspend(refill_thread);
524 		if (qdf_status != QDF_STATUS_SUCCESS)
525 			return qdf_status;
526 	}
527 
528 	qdf_status = dp_rx_tm_suspend(&dp_ext_hdl->rx_tm_hdl);
529 	if (QDF_IS_STATUS_ERROR(qdf_status) && refill_thread->enabled)
530 		dp_rx_refill_thread_resume(refill_thread);
531 
532 ret:
533 	return qdf_status;
534 }
535 
536 /**
537  * dp_rx_enqueue_pkt() - enqueue packet(s) into the thread
538  * @soc: ol_txrx_soc_handle object
539  * @nbuf_list: list of packets to be queued into the rx_thread
540  *
541  * The function accepts a list of skbs connected by the skb->next pointer and
542  * queues them into a RX thread to be sent to the stack.
543  *
544  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
545  */
546 static inline
dp_rx_enqueue_pkt(ol_txrx_soc_handle soc,qdf_nbuf_t nbuf_list)547 QDF_STATUS dp_rx_enqueue_pkt(ol_txrx_soc_handle soc, qdf_nbuf_t nbuf_list)
548 {
549 	struct dp_txrx_handle *dp_ext_hdl;
550 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
551 
552 	if (!soc || !nbuf_list) {
553 		qdf_status = QDF_STATUS_E_INVAL;
554 		dp_err("invalid input params soc %pK nbuf %pK"
555 		       , soc, nbuf_list);
556 		goto ret;
557 	}
558 
559 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
560 	if (!dp_ext_hdl) {
561 		qdf_status = QDF_STATUS_E_FAULT;
562 		goto ret;
563 	}
564 
565 	qdf_status = dp_rx_tm_enqueue_pkt(&dp_ext_hdl->rx_tm_hdl, nbuf_list);
566 ret:
567 	return qdf_status;
568 }
569 
570 /**
571  * dp_rx_gro_flush_ind() - Flush GRO packets for a given RX CTX Id
572  * @soc: ol_txrx_soc_handle object
573  * @rx_ctx_id: Context Id (Thread for which GRO packets need to be flushed)
574  * @flush_code: flush_code differentiating normal_flush from low_tput_flush
575  *
576  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
577  */
578 static inline
dp_rx_gro_flush_ind(ol_txrx_soc_handle soc,int rx_ctx_id,enum dp_rx_gro_flush_code flush_code)579 QDF_STATUS dp_rx_gro_flush_ind(ol_txrx_soc_handle soc, int rx_ctx_id,
580 			       enum dp_rx_gro_flush_code flush_code)
581 {
582 	struct dp_txrx_handle *dp_ext_hdl;
583 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
584 
585 	if (!soc) {
586 		qdf_status = QDF_STATUS_E_INVAL;
587 		dp_err("invalid input param soc %pK", soc);
588 		goto ret;
589 	}
590 
591 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
592 	if (!dp_ext_hdl) {
593 		qdf_status = QDF_STATUS_E_FAULT;
594 		goto ret;
595 	}
596 
597 	qdf_status = dp_rx_tm_gro_flush_ind(&dp_ext_hdl->rx_tm_hdl, rx_ctx_id,
598 					    flush_code);
599 ret:
600 	return qdf_status;
601 }
602 
603 /**
604  * dp_txrx_ext_dump_stats() - dump txrx external module stats
605  * @soc: ol_txrx_soc_handle object
606  * @stats_id: id  for the module whose stats are needed
607  *
608  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
609  */
dp_txrx_ext_dump_stats(ol_txrx_soc_handle soc,uint8_t stats_id)610 static inline QDF_STATUS dp_txrx_ext_dump_stats(ol_txrx_soc_handle soc,
611 						uint8_t stats_id)
612 {
613 	struct dp_txrx_handle *dp_ext_hdl;
614 	QDF_STATUS qdf_status;
615 
616 	if (!soc) {
617 		dp_err("invalid input params soc %pK", soc);
618 		return QDF_STATUS_E_INVAL;
619 	}
620 
621 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
622 	if (!dp_ext_hdl)
623 		return QDF_STATUS_E_FAULT;
624 
625 	if (stats_id == CDP_DP_RX_THREAD_STATS)
626 		qdf_status = dp_rx_tm_dump_stats(&dp_ext_hdl->rx_tm_hdl);
627 	else
628 		qdf_status = QDF_STATUS_E_INVAL;
629 
630 	return qdf_status;
631 }
632 
633 /**
634  * dp_rx_get_napi_context() - get NAPI context for a RX CTX ID
635  * @soc: ol_txrx_soc_handle object
636  * @rx_ctx_id: RX context ID (RX thread ID) corresponding to which NAPI is
637  *             needed
638  *
639  * Return: NULL on failure, else pointer to NAPI corresponding to rx_ctx_id
640  */
641 static inline
dp_rx_get_napi_context(ol_txrx_soc_handle soc,uint8_t rx_ctx_id)642 qdf_napi_struct *dp_rx_get_napi_context(ol_txrx_soc_handle soc,
643 					uint8_t rx_ctx_id)
644 {
645 	struct dp_txrx_handle *dp_ext_hdl;
646 
647 	if (!soc) {
648 		dp_err("soc in NULL!");
649 		return NULL;
650 	}
651 
652 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
653 	if (!dp_ext_hdl) {
654 		dp_err("dp_ext_hdl in NULL!");
655 		return NULL;
656 	}
657 
658 	return dp_rx_tm_get_napi_context(&dp_ext_hdl->rx_tm_hdl, rx_ctx_id);
659 }
660 
661 /**
662  * dp_txrx_set_cpu_mask() - set CPU mask for RX threads
663  * @soc: ol_txrx_soc_handle object
664  * @new_mask: New CPU mask pointer
665  *
666  * Return: QDF_STATUS_SUCCESS on success, error qdf status on failure
667  */
668 static inline
dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc,qdf_cpu_mask * new_mask)669 QDF_STATUS dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc, qdf_cpu_mask *new_mask)
670 {
671 	struct dp_txrx_handle *dp_ext_hdl;
672 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
673 
674 	if (!soc) {
675 		qdf_status = QDF_STATUS_E_INVAL;
676 		goto ret;
677 	}
678 
679 	dp_ext_hdl = cdp_soc_get_dp_txrx_handle(soc);
680 	if (!dp_ext_hdl) {
681 		qdf_status = QDF_STATUS_E_FAULT;
682 		goto ret;
683 	}
684 
685 	qdf_status = dp_rx_tm_set_cpu_mask(&dp_ext_hdl->rx_tm_hdl, new_mask);
686 
687 ret:
688 	return qdf_status;
689 }
690 
691 #else
692 
693 static inline
dp_txrx_init(ol_txrx_soc_handle soc,uint8_t pdev_id,struct dp_txrx_config * config)694 QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id,
695 			struct dp_txrx_config *config)
696 {
697 	return QDF_STATUS_SUCCESS;
698 }
699 
dp_txrx_deinit(ol_txrx_soc_handle soc)700 static inline QDF_STATUS dp_txrx_deinit(ol_txrx_soc_handle soc)
701 {
702 	return QDF_STATUS_SUCCESS;
703 }
704 
dp_txrx_flush_pkts_by_vdev_id(ol_txrx_soc_handle soc,uint8_t vdev_id)705 static inline QDF_STATUS dp_txrx_flush_pkts_by_vdev_id(ol_txrx_soc_handle soc,
706 						       uint8_t vdev_id)
707 {
708 	return QDF_STATUS_SUCCESS;
709 }
710 
dp_txrx_resume(ol_txrx_soc_handle soc)711 static inline QDF_STATUS dp_txrx_resume(ol_txrx_soc_handle soc)
712 {
713 	return QDF_STATUS_SUCCESS;
714 }
715 
dp_txrx_suspend(ol_txrx_soc_handle soc)716 static inline QDF_STATUS dp_txrx_suspend(ol_txrx_soc_handle soc)
717 {
718 	return QDF_STATUS_SUCCESS;
719 }
720 
721 static inline
dp_rx_enqueue_pkt(ol_txrx_soc_handle soc,qdf_nbuf_t nbuf_list)722 QDF_STATUS dp_rx_enqueue_pkt(ol_txrx_soc_handle soc, qdf_nbuf_t nbuf_list)
723 {
724 	return QDF_STATUS_SUCCESS;
725 }
726 
727 static inline
dp_rx_gro_flush_ind(ol_txrx_soc_handle soc,int rx_ctx_id,enum dp_rx_gro_flush_code flush_code)728 QDF_STATUS dp_rx_gro_flush_ind(ol_txrx_soc_handle soc, int rx_ctx_id,
729 			       enum dp_rx_gro_flush_code flush_code)
730 {
731 	return QDF_STATUS_SUCCESS;
732 }
733 
dp_txrx_ext_dump_stats(ol_txrx_soc_handle soc,uint8_t stats_id)734 static inline QDF_STATUS dp_txrx_ext_dump_stats(ol_txrx_soc_handle soc,
735 						uint8_t stats_id)
736 {
737 	return QDF_STATUS_SUCCESS;
738 }
739 
740 static inline
dp_rx_get_napi_context(ol_txrx_soc_handle soc,uint8_t rx_ctx_id)741 qdf_napi_struct *dp_rx_get_napi_context(ol_txrx_soc_handle soc,
742 					uint8_t rx_ctx_id)
743 {
744 	return NULL;
745 }
746 
747 static inline
dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc,qdf_cpu_mask * new_mask)748 QDF_STATUS dp_txrx_set_cpu_mask(ol_txrx_soc_handle soc, qdf_cpu_mask *new_mask)
749 {
750 	return QDF_STATUS_SUCCESS;
751 }
752 
753 #endif /* FEATURE_WLAN_DP_RX_THREADS */
754 
755 /**
756  * dp_rx_tm_get_pending() - get number of frame in thread
757  * nbuf queue pending
758  * @soc: ol_txrx_soc_handle object
759  *
760  * Return: number of frames
761  */
762 int dp_rx_tm_get_pending(ol_txrx_soc_handle soc);
763 #endif /* __WLAN_DP_RX_THREAD_H */
764