xref: /wlan-dirver/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
1 /*
2  * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * @file cdp_txrx_misc.h
21  * @brief Define the host data path miscellaneous API functions
22  * called by the host control SW and the OS interface module
23  */
24 #ifndef _CDP_TXRX_MISC_H_
25 #define _CDP_TXRX_MISC_H_
26 
27 #include "cdp_txrx_handle.h"
28 /**
29  * cdp_tx_non_std() - Allow the control-path SW to send data frames
30  *
31  * @soc - data path soc handle
32  * @data_vdev - which vdev should transmit the tx data frames
33  * @tx_spec - what non-standard handling to apply to the tx data frames
34  * @msdu_list - NULL-terminated list of tx MSDUs
35  *
36  * Generally, all tx data frames come from the OS shim into the txrx layer.
37  * However, there are rare cases such as TDLS messaging where the UMAC
38  * control-path SW creates tx data frames.
39  *  This UMAC SW can call this function to provide the tx data frames to
40  *  the txrx layer.
41  *  The UMAC SW can request a callback for these data frames after their
42  *  transmission completes, by using the ol_txrx_data_tx_cb_set function
43  *  to register a tx completion callback, and by specifying
44  *  ol_tx_spec_no_free as the tx_spec arg when giving the frames to
45  *  ol_tx_non_std.
46  *  The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11),
47  *  as specified by ol_cfg_frame_type().
48  *
49  *  Return: null - success, skb - failure
50  */
51 static inline qdf_nbuf_t
52 cdp_tx_non_std(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
53 		enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
54 {
55 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
56 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
57 			"%s invalid instance", __func__);
58 		return NULL;
59 	}
60 
61 	if (soc->ops->misc_ops->tx_non_std)
62 		return soc->ops->misc_ops->tx_non_std(
63 			vdev, tx_spec, msdu_list);
64 	return NULL;
65 }
66 
67 /**
68  * cdp_set_ibss_vdev_heart_beat_timer() - Update ibss vdev heart
69  * beat timer
70  * @soc - data path soc handle
71  * @vdev - vdev handle
72  * @timer_value_sec - new heart beat timer value
73  *
74  * Return: Old timer value set in vdev.
75  */
76 static inline uint16_t
77 cdp_set_ibss_vdev_heart_beat_timer(ol_txrx_soc_handle soc,
78 		struct cdp_vdev *vdev, uint16_t timer_value_sec)
79 {
80 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
81 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
82 			"%s invalid instance", __func__);
83 		return 0;
84 	}
85 
86 	if (soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer)
87 		return soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer(
88 			vdev, timer_value_sec);
89 
90 	return 0;
91 }
92 
93 /**
94  * cdp_set_wisa_mode() - set wisa mode
95  * @soc - data path soc handle
96  * @vdev - vdev handle
97  * @enable - enable or disable
98  *
99  * Return: QDF_STATUS_SUCCESS mode enable success
100  */
101 static inline QDF_STATUS
102 cdp_set_wisa_mode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool enable)
103 {
104 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
105 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
106 			"%s invalid instance", __func__);
107 		return QDF_STATUS_E_INVAL;
108 	}
109 
110 	if (soc->ops->misc_ops->set_wisa_mode)
111 		return soc->ops->misc_ops->set_wisa_mode(vdev, enable);
112 	return QDF_STATUS_SUCCESS;
113 }
114 
115 /**
116  * cdp_data_stall_cb_register() - register data stall callback
117  * @soc - data path soc handle
118  * @cb - callback function
119  *
120  * Return: QDF_STATUS_SUCCESS register success
121  */
122 static inline QDF_STATUS cdp_data_stall_cb_register(ol_txrx_soc_handle soc,
123 						    data_stall_detect_cb cb)
124 {
125 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
126 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
127 			"%s invalid instance", __func__);
128 		return QDF_STATUS_E_INVAL;
129 	}
130 
131 	if (soc->ops->misc_ops->txrx_data_stall_cb_register)
132 		return soc->ops->misc_ops->txrx_data_stall_cb_register(cb);
133 	return QDF_STATUS_SUCCESS;
134 }
135 
136 /**
137  * cdp_data_stall_cb_deregister() - de-register data stall callback
138  * @soc - data path soc handle
139  * @cb - callback function
140  *
141  * Return: QDF_STATUS_SUCCESS de-register success
142  */
143 static inline QDF_STATUS cdp_data_stall_cb_deregister(ol_txrx_soc_handle soc,
144 						      data_stall_detect_cb cb)
145 {
146 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
147 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
148 			"%s invalid instance", __func__);
149 		return QDF_STATUS_E_INVAL;
150 	}
151 
152 	if (soc->ops->misc_ops->txrx_data_stall_cb_deregister)
153 		return soc->ops->misc_ops->txrx_data_stall_cb_deregister(cb);
154 	return QDF_STATUS_SUCCESS;
155 }
156 
157 /**
158  * cdp_post_data_stall_event() - post data stall event
159  * @soc - data path soc handle
160  * @indicator: Module triggering data stall
161  * @data_stall_type: data stall event type
162  * @pdev_id: pdev id
163  * @vdev_id_bitmap: vdev id bitmap
164  * @recovery_type: data stall recovery type
165  *
166  * Return: None
167  */
168 static inline void
169 cdp_post_data_stall_event(ol_txrx_soc_handle soc,
170 			  enum data_stall_log_event_indicator indicator,
171 			  enum data_stall_log_event_type data_stall_type,
172 			  uint32_t pdev_id, uint32_t vdev_id_bitmap,
173 			  enum data_stall_log_recovery_type recovery_type)
174 {
175 	if (!soc || !soc->ops) {
176 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
177 			"%s invalid instance", __func__);
178 		QDF_BUG(0);
179 		return;
180 	}
181 
182 	if (!soc->ops->misc_ops ||
183 	    !soc->ops->misc_ops->txrx_post_data_stall_event)
184 		return;
185 
186 	soc->ops->misc_ops->txrx_post_data_stall_event(
187 				indicator, data_stall_type, pdev_id,
188 				vdev_id_bitmap, recovery_type);
189 }
190 
191 /**
192  * cdp_set_wmm_param() - set wmm parameter
193  * @soc - data path soc handle
194  * @pdev - device instance pointer
195  * @wmm_param - wmm parameter
196  *
197  * Return: none
198  */
199 static inline void
200 cdp_set_wmm_param(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
201 		      struct ol_tx_wmm_param_t wmm_param)
202 {
203 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
204 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
205 			"%s invalid instance", __func__);
206 		return;
207 	}
208 
209 	if (soc->ops->misc_ops->set_wmm_param)
210 		return soc->ops->misc_ops->set_wmm_param(
211 			pdev, wmm_param);
212 
213 	return;
214 }
215 
216 /**
217  * cdp_runtime_suspend() - suspend
218  * @soc - data path soc handle
219  * @pdev - device instance pointer
220  *
221  * Return: QDF_STATUS_SUCCESS suspend success
222  */
223 static inline QDF_STATUS cdp_runtime_suspend(ol_txrx_soc_handle soc,
224 		struct cdp_pdev *pdev)
225 {
226 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
227 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
228 			"%s invalid instance", __func__);
229 		return QDF_STATUS_E_INVAL;
230 	}
231 
232 	if (soc->ops->misc_ops->runtime_suspend)
233 		return soc->ops->misc_ops->runtime_suspend(pdev);
234 
235 	return QDF_STATUS_SUCCESS;
236 }
237 
238 /**
239  * cdp_runtime_resume() - resume
240  * @soc - data path soc handle
241  * @pdev - device instance pointer
242  *
243  * Return: QDF_STATUS_SUCCESS suspend success
244  */
245 static inline QDF_STATUS cdp_runtime_resume(ol_txrx_soc_handle soc,
246 		struct cdp_pdev *pdev)
247 {
248 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
249 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
250 			"%s invalid instance", __func__);
251 		return QDF_STATUS_E_INVAL;
252 	}
253 
254 	if (soc->ops->misc_ops->runtime_resume)
255 		return soc->ops->misc_ops->runtime_resume(pdev);
256 
257 	return QDF_STATUS_SUCCESS;
258 }
259 
260 /**
261  * cdp_hl_tdls_flag_reset() - tdls flag reset
262  * @soc - data path soc handle
263  * @vdev - virtual interface handle pointer
264  * @flag
265  *
266  * Return: none
267  */
268 static inline void
269 cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, struct cdp_vdev *vdev, bool flag)
270 {
271 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
272 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
273 			"%s invalid instance", __func__);
274 		return;
275 	}
276 
277 	if (soc->ops->misc_ops->hl_tdls_flag_reset)
278 		return soc->ops->misc_ops->hl_tdls_flag_reset(vdev, flag);
279 
280 	return;
281 }
282 
283 /**
284  * cdp_get_opmode() - get vdev operation mode
285  * @soc - data path soc handle
286  * @vdev - virtual interface instance
287  *
288  * Return virtual device operational mode
289  *      op_mode_ap,
290  *      op_mode_ibss,
291  *      op_mode_sta,
292  *      op_mode_monitor,
293  *      op_mode_ocb,
294  *
295  * return interface id
296  *        0 unknown interface
297  */
298 static inline int
299 cdp_get_opmode(ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
300 {
301 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
302 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
303 			"%s invalid instance", __func__);
304 		return 0;
305 	}
306 
307 	if (soc->ops->misc_ops->get_opmode)
308 		return soc->ops->misc_ops->get_opmode(vdev);
309 	return 0;
310 }
311 
312 /**
313  * cdp_get_vdev_id() - get vdev id
314  * @soc - data path soc handle
315  * @vdev - virtual interface instance
316  *
317  * get virtual interface id
318  *
319  * return interface id
320  *        0 unknown interface
321  */
322 static inline uint16_t
323 cdp_get_vdev_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
324 {
325 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
326 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
327 			"%s invalid instance", __func__);
328 		return 0;
329 	}
330 
331 	if (soc->ops->misc_ops->get_vdev_id)
332 		return soc->ops->misc_ops->get_vdev_id(vdev);
333 	return 0;
334 }
335 
336 /**
337  * cdp_get_tx_ack_stats() - get tx ack count for vdev
338  * @soc - data path soc handle
339  * @pdev - data path device instance
340  * @vdev_id - vdev id
341  *
342  * return tx ack count
343  *          0 invalid count
344  */
345 static inline uint32_t
346 cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
347 		     uint8_t vdev_id)
348 {
349 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
350 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
351 			"%s invalid instance", __func__);
352 		return 0;
353 	}
354 
355 	if (soc->ops->misc_ops->get_tx_ack_stats)
356 		return soc->ops->misc_ops->get_tx_ack_stats(pdev, vdev_id);
357 
358 	return 0;
359 }
360 
361 /**
362  * cdp_bad_peer_txctl_set_setting() - TBD
363  * @soc - data path soc handle
364  * @pdev - data path device instance
365  * @enable -
366  * @period -
367  * @txq_limit -
368  *
369  * TBD
370  *
371  * Return: none
372  */
373 static inline void
374 cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
375 		int enable, int period, int txq_limit)
376 {
377 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
378 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
379 			"%s invalid instance", __func__);
380 		return;
381 	}
382 
383 	if (soc->ops->misc_ops->bad_peer_txctl_set_setting)
384 		return soc->ops->misc_ops->bad_peer_txctl_set_setting(pdev,
385 			enable, period, txq_limit);
386 	return;
387 }
388 
389 /**
390  * cdp_bad_peer_txctl_update_threshold() - TBD
391  * @soc - data path soc handle
392  * @pdev - data path device instance
393  * @level -
394  * @tput_thresh -
395  * @tx_limit -
396  *
397  * TBD
398  *
399  * Return: none
400  */
401 static inline void
402 cdp_bad_peer_txctl_update_threshold(ol_txrx_soc_handle soc,
403 		struct cdp_pdev *pdev,
404 		int level, int tput_thresh, int tx_limit)
405 {
406 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
407 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
408 			"%s invalid instance", __func__);
409 		return;
410 	}
411 
412 	if (soc->ops->misc_ops->bad_peer_txctl_update_threshold)
413 		return soc->ops->misc_ops->bad_peer_txctl_update_threshold(
414 			pdev, level, tput_thresh, tx_limit);
415 	return;
416 }
417 
418 /**
419  * cdp_mark_first_wakeup_packet() - set flag to indicate that
420  *    fw is compatible for marking first packet after wow wakeup
421  * @soc - data path soc handle
422  * @value: 1 for enabled/ 0 for disabled
423  *
424  * Return: None
425  */
426 static inline void cdp_mark_first_wakeup_packet(ol_txrx_soc_handle soc,
427 		uint8_t value)
428 {
429 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
430 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
431 			"%s invalid instance", __func__);
432 		return;
433 	}
434 
435 	if (soc->ops->misc_ops->mark_first_wakeup_packet)
436 		return soc->ops->misc_ops->mark_first_wakeup_packet(value);
437 	return;
438 }
439 
440 
441 /**
442  * cds_update_mac_id() - update mac_id for vdev
443  * @soc - data path soc handle
444  * @vdev_id: vdev id
445  * @mac_id: mac id
446  *
447  * Return: none
448  */
449 static inline void cdp_update_mac_id(void *psoc, uint8_t vdev_id,
450 		uint8_t mac_id)
451 {
452 	ol_txrx_soc_handle soc = psoc;
453 
454 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
455 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
456 			"%s invalid instance", __func__);
457 		return;
458 	}
459 
460 	if (soc->ops->misc_ops->update_mac_id)
461 		return soc->ops->misc_ops->update_mac_id(vdev_id, mac_id);
462 	return;
463 }
464 
465 /**
466  * cdp_flush_rx_frames() - flush cached rx frames
467  * @soc - data path soc handle
468  * @peer: peer
469  * @drop: set flag to drop frames
470  *
471  * Return: None
472  */
473 static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, void *peer,
474 		bool drop)
475 {
476 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
477 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
478 			"%s invalid instance", __func__);
479 		return;
480 	}
481 
482 	if (soc->ops->misc_ops->flush_rx_frames)
483 		return soc->ops->misc_ops->flush_rx_frames(peer, drop);
484 	return;
485 }
486 
487 /*
488  * cdp_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets
489  *   that has been forwarded from txrx layer without going to upper layers.
490  * @vdev_id: vdev id
491  * @fwd_tx_packets: pointer to forwarded tx packets count parameter
492  * @fwd_rx_packets: pointer to forwarded rx packets count parameter
493  *
494  * Return: status -> A_OK - success, A_ERROR - failure
495  */
496 static inline A_STATUS cdp_get_intra_bss_fwd_pkts_count(
497 		ol_txrx_soc_handle soc, uint8_t vdev_id,
498 		uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets)
499 {
500 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
501 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
502 			"%s invalid instance", __func__);
503 		return 0;
504 	}
505 
506 	if (soc->ops->misc_ops->get_intra_bss_fwd_pkts_count)
507 		return soc->ops->misc_ops->get_intra_bss_fwd_pkts_count(
508 			vdev_id, fwd_tx_packets, fwd_rx_packets);
509 
510 	return 0;
511 }
512 
513 /**
514  * cdp_pkt_log_init() - API to initialize packet log
515  * @handle: pdev handle
516  * @scn: HIF context
517  *
518  * Return: void
519  */
520 static inline void cdp_pkt_log_init(ol_txrx_soc_handle soc,
521 		struct cdp_pdev *pdev, void *scn)
522 {
523 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
524 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
525 			"%s invalid instance", __func__);
526 		return;
527 	}
528 
529 	if (soc->ops->misc_ops->pkt_log_init)
530 		return soc->ops->misc_ops->pkt_log_init(pdev, scn);
531 
532 	return;
533 }
534 
535 /**
536  * cdp_pkt_log_con_service() - API to connect packet log service
537  * @handle: pdev handle
538  * @scn: HIF context
539  *
540  * Return: void
541  */
542 static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc,
543 		struct cdp_pdev *pdev, void *scn)
544 {
545 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
546 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
547 			"%s invalid instance", __func__);
548 		return;
549 	}
550 
551 	if (soc->ops->misc_ops->pkt_log_con_service)
552 		return soc->ops->misc_ops->pkt_log_con_service(pdev, scn);
553 
554 	return;
555 }
556 
557 /**
558  * cdp_get_num_rx_contexts() - API to get the number of RX contexts
559  * @soc: soc handle
560  *
561  * Return: number of RX contexts
562  */
563 static inline int cdp_get_num_rx_contexts(ol_txrx_soc_handle soc)
564 {
565 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
566 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
567 			  "%s invalid instance", __func__);
568 		return 0;
569 	}
570 
571 	if (soc->ops->misc_ops->get_num_rx_contexts)
572 		return soc->ops->misc_ops->get_num_rx_contexts(soc);
573 
574 	return 0;
575 }
576 
577 /**
578  * cdp_register_packetdump_cb() - API to register packetdump callback
579  *
580  * Register TX/RX callback for data packets, during connection. And per packet
581  * stats will be passed to user-space by @tx_cb/@rx_cb.
582  *
583  * @soc: soc handle
584  * @tx_cb: tx packet callback
585  * @rx_cb: rx packet callback
586  *
587  * Return: void
588  */
589 static inline void cdp_register_packetdump_cb(ol_txrx_soc_handle soc,
590 					      ol_txrx_pktdump_cb tx_cb,
591 					      ol_txrx_pktdump_cb rx_cb)
592 {
593 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
594 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
595 			  "%s invalid instance", __func__);
596 		return;
597 	}
598 
599 	if (soc->ops->misc_ops->register_pktdump_cb)
600 		return soc->ops->misc_ops->register_pktdump_cb(tx_cb, rx_cb);
601 }
602 
603 /**
604  * cdp_deregister_packetdump_cb() - API to unregister packetdump callback
605  *
606  * Deregister callback for TX/RX data packets.
607  *
608  * @soc: soc handle
609  *
610  * Return: void
611  */
612 static inline void cdp_deregister_packetdump_cb(ol_txrx_soc_handle soc)
613 {
614 	if (!soc || !soc->ops || !soc->ops->misc_ops) {
615 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
616 			  "%s invalid instance", __func__);
617 		return;
618 	}
619 
620 	if (soc->ops->misc_ops->unregister_pktdump_cb)
621 		return soc->ops->misc_ops->unregister_pktdump_cb();
622 }
623 #endif /* _CDP_TXRX_MISC_H_ */
624