xref: /wlan-dirver/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h (revision bea437e2293c3d4fb1b5704fcf633aedac996962)
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_flow_ctrl_legacy.h
21  * @brief Define the host data path legacy flow control API
22  * functions
23  */
24 #ifndef _CDP_TXRX_FC_LEG_H_
25 #define _CDP_TXRX_FC_LEG_H_
26 #include <cdp_txrx_mob_def.h>
27 #include "cdp_txrx_handle.h"
28 
29 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
30 
31 /**
32  * cdp_hl_fc_register() - Register HL flow control callback.
33  * @soc: data path soc handle
34  * @pdev_id: datapath pdev identifier
35  * @flowcontrol: callback function pointer to stop/start OS netdev queues
36  *
37  * Register flow control callback.
38  *
39  * Returns: 0 for success
40  */
41 static inline int
42 cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
43 		   tx_pause_callback flowcontrol)
44 {
45 	if (!soc || !soc->ops) {
46 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
47 			  "%s invalid instance", __func__);
48 		QDF_BUG(0);
49 		return -EINVAL;
50 	}
51 
52 	if (!soc->ops->l_flowctl_ops ||
53 	    !soc->ops->l_flowctl_ops->register_tx_flow_control)
54 		return -EINVAL;
55 
56 	return soc->ops->l_flowctl_ops->register_tx_flow_control(soc, pdev_id,
57 								 flowcontrol);
58 }
59 
60 static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc,
61 					 uint8_t vdev_id, uint32_t chan_freq)
62 {
63 	if (!soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit)
64 		return 0;
65 
66 	return soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit(soc, vdev_id,
67 							       chan_freq);
68 }
69 
70 static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc,
71 						uint8_t vdev_id,
72 					    enum netif_action_type action)
73 {
74 	if (!soc->ops->l_flowctl_ops->set_vdev_os_queue_status)
75 		return -EINVAL;
76 
77 	return soc->ops->l_flowctl_ops->set_vdev_os_queue_status(soc,
78 								 vdev_id,
79 								 action);
80 }
81 #else
82 static inline int
83 cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
84 		   tx_pause_callback flowcontrol)
85 {
86 	return 0;
87 }
88 
89 static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc,
90 					 uint8_t vdev_id, uint32_t chan_freq)
91 {
92 	return 0;
93 }
94 
95 static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc,
96 						uint8_t vdev_id,
97 						enum netif_action_type action)
98 {
99 	return 0;
100 }
101 
102 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
103 
104 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
105 /**
106  * cdp_fc_register() - Register flow control callback function pointer
107  * @soc - data path soc handle
108  * @vdev_id - virtual interface id to register flow control
109  * @flowControl - callback function pointer
110  * @osif_fc_ctx - client context pointer
111  * @flow_control_is_pause: is vdev paused by flow control
112  *
113  * Register flow control callback function pointer and client context pointer
114  *
115  * return 0 success
116  */
117 static inline int
118 cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
119 		ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
120 		ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
121 {
122 	if (!soc || !soc->ops) {
123 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
124 			"%s invalid instance", __func__);
125 		QDF_BUG(0);
126 		return 0;
127 	}
128 
129 	if (!soc->ops->l_flowctl_ops ||
130 	    !soc->ops->l_flowctl_ops->register_tx_flow_control)
131 		return 0;
132 
133 	return soc->ops->l_flowctl_ops->register_tx_flow_control(
134 			soc, vdev_id, flowcontrol, osif_fc_ctx,
135 			flow_control_is_pause);
136 }
137 #else
138 static inline int
139 cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
140 		ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
141 		ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
142 {
143 	return 0;
144 }
145 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
146 /**
147  * cdp_fc_deregister() - remove flow control instance
148  * @soc - data path soc handle
149  * @vdev_id - virtual interface id to register flow control
150  *
151  * remove flow control instance
152  *
153  * return 0 success
154  */
155 static inline int
156 cdp_fc_deregister(ol_txrx_soc_handle soc, uint8_t vdev_id)
157 {
158 	if (!soc || !soc->ops) {
159 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
160 			"%s invalid instance", __func__);
161 		QDF_BUG(0);
162 		return 0;
163 	}
164 
165 	if (!soc->ops->l_flowctl_ops ||
166 	    !soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb)
167 		return 0;
168 
169 	return soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb(
170 			soc, vdev_id);
171 }
172 
173 /**
174  * cdp_fc_get_tx_resource() - get data path resource count
175  * @soc: data path soc handle
176  * @pdev_id: datapath pdev ID
177  * @peer_addr: peer mac address
178  * @low_watermark: low resource threshold
179  * @high_watermark_offset: high resource threshold
180  *
181  * get data path resource count
182  *
183  * return true enough data path resource available
184  *        false resource is not avaialbe
185  */
186 static inline bool
187 cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t pdev_id,
188 		       struct qdf_mac_addr peer_addr,
189 		       unsigned int low_watermark,
190 		       unsigned int high_watermark_offset)
191 {
192 	if (!soc || !soc->ops) {
193 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
194 			"%s invalid instance", __func__);
195 		QDF_BUG(0);
196 		return false;
197 	}
198 
199 	if (!soc->ops->l_flowctl_ops ||
200 	    !soc->ops->l_flowctl_ops->get_tx_resource)
201 		return false;
202 
203 	return soc->ops->l_flowctl_ops->get_tx_resource(soc, pdev_id, peer_addr,
204 							low_watermark,
205 							high_watermark_offset);
206 }
207 
208 /**
209  * cdp_fc_ll_set_tx_pause_q_depth() - set pause queue depth
210  * @soc - data path soc handle
211  * @vdev_id - virtual interface id to register flow control
212  * @pause_q_depth - pending tx queue delth
213  *
214  * set pause queue depth
215  *
216  * return 0 success
217  */
218 static inline int
219 cdp_fc_ll_set_tx_pause_q_depth(ol_txrx_soc_handle soc,
220 		uint8_t vdev_id, int pause_q_depth)
221 {
222 	if (!soc || !soc->ops) {
223 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
224 			"%s invalid instance", __func__);
225 		QDF_BUG(0);
226 		return 0;
227 	}
228 
229 	if (!soc->ops->l_flowctl_ops ||
230 	    !soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth)
231 		return 0;
232 
233 	return soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth(
234 			soc, vdev_id, pause_q_depth);
235 
236 }
237 
238 /**
239  * cdp_fc_vdev_flush() - flush tx queue
240  * @soc: data path soc handle
241  * @vdev_id: id of vdev
242  *
243  * flush tx queue
244  *
245  * return None
246  */
247 static inline void
248 cdp_fc_vdev_flush(ol_txrx_soc_handle soc, uint8_t vdev_id)
249 {
250 	if (!soc || !soc->ops) {
251 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
252 			"%s invalid instance", __func__);
253 		QDF_BUG(0);
254 		return;
255 	}
256 
257 	if (!soc->ops->l_flowctl_ops ||
258 	    !soc->ops->l_flowctl_ops->vdev_flush)
259 		return;
260 
261 	soc->ops->l_flowctl_ops->vdev_flush(soc, vdev_id);
262 }
263 
264 /**
265  * cdp_fc_vdev_pause() - pause tx scheduler on vdev
266  * @soc: data path soc handle
267  * @vdev_id: id of vdev
268  * @reason: pause reason
269  * @pause_type: type of pause
270  *
271  * pause tx scheduler on vdev
272  *
273  * return None
274  */
275 static inline void
276 cdp_fc_vdev_pause(ol_txrx_soc_handle soc, uint8_t vdev_id,
277 		  uint32_t reason, uint32_t pause_type)
278 {
279 	if (!soc || !soc->ops) {
280 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
281 			"%s invalid instance", __func__);
282 		QDF_BUG(0);
283 		return;
284 	}
285 
286 	if (!soc->ops->l_flowctl_ops ||
287 	    !soc->ops->l_flowctl_ops->vdev_pause)
288 		return;
289 
290 	soc->ops->l_flowctl_ops->vdev_pause(soc, vdev_id, reason, pause_type);
291 }
292 
293 /**
294  * cdp_fc_vdev_unpause() - resume tx scheduler on vdev
295  * @soc: data path soc handle
296  * @vdev_id: id of vdev
297  * @reason: pause reason
298  * @pause_type: type of pause
299  *
300  * resume tx scheduler on vdev
301  *
302  * return None
303  */
304 static inline void
305 cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, uint8_t vdev_id,
306 		    uint32_t reason, uint32_t pause_type)
307 {
308 	if (!soc || !soc->ops) {
309 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
310 			"%s invalid instance", __func__);
311 		return;
312 	}
313 
314 	if (!soc->ops->l_flowctl_ops ||
315 	    !soc->ops->l_flowctl_ops->vdev_unpause)
316 		return;
317 
318 	soc->ops->l_flowctl_ops->vdev_unpause(soc, vdev_id, reason,
319 					      pause_type);
320 }
321 #endif /* _CDP_TXRX_FC_LEG_H_ */
322