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