xref: /wlan-dirver/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h (revision 1f55ed1a9f5050d8da228aa8dd3fff7c0242aa71)
1 /*
2  * Copyright (c) 2016-2018 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  * @sta_id - local peer id
170  * @low_watermark - low resource threshold
171  * @high_watermark_offset - high resource threshold
172  *
173  * get data path resource count
174  *
175  * return true enough data path resource available
176  *        false resource is not avaialbe
177  */
178 static inline bool
179 cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t sta_id,
180 		unsigned int low_watermark, unsigned int high_watermark_offset)
181 {
182 	if (!soc || !soc->ops) {
183 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
184 			"%s invalid instance", __func__);
185 		QDF_BUG(0);
186 		return false;
187 	}
188 
189 	if (!soc->ops->l_flowctl_ops ||
190 	    !soc->ops->l_flowctl_ops->get_tx_resource)
191 		return false;
192 
193 	return soc->ops->l_flowctl_ops->get_tx_resource(sta_id,
194 			low_watermark, high_watermark_offset);
195 }
196 
197 /**
198  * cdp_fc_ll_set_tx_pause_q_depth() - set pause queue depth
199  * @soc - data path soc handle
200  * @vdev_id - virtual interface id to register flow control
201  * @pause_q_depth - pending tx queue delth
202  *
203  * set pause queue depth
204  *
205  * return 0 success
206  */
207 static inline int
208 cdp_fc_ll_set_tx_pause_q_depth(ol_txrx_soc_handle soc,
209 		uint8_t vdev_id, int pause_q_depth)
210 {
211 	if (!soc || !soc->ops) {
212 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
213 			"%s invalid instance", __func__);
214 		QDF_BUG(0);
215 		return 0;
216 	}
217 
218 	if (!soc->ops->l_flowctl_ops ||
219 	    !soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth)
220 		return 0;
221 
222 	return soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth(
223 			vdev_id, pause_q_depth);
224 
225 }
226 
227 /**
228  * cdp_fc_vdev_flush() - flush tx queue
229  * @soc - data path soc handle
230  * @vdev - virtual interface context pointer
231  *
232  * flush tx queue
233  *
234  * return None
235  */
236 static inline void
237 cdp_fc_vdev_flush(ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
238 {
239 	if (!soc || !soc->ops) {
240 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
241 			"%s invalid instance", __func__);
242 		QDF_BUG(0);
243 		return;
244 	}
245 
246 	if (!soc->ops->l_flowctl_ops ||
247 	    !soc->ops->l_flowctl_ops->vdev_flush)
248 		return;
249 
250 	soc->ops->l_flowctl_ops->vdev_flush(vdev);
251 }
252 
253 /**
254  * cdp_fc_vdev_pause() - pause tx scheduler on vdev
255  * @soc - data path soc handle
256  * @vdev - virtual interface context pointer
257  * @reason - pause reason
258  *
259  * pause tx scheduler on vdev
260  *
261  * return None
262  */
263 static inline void
264 cdp_fc_vdev_pause(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
265 		uint32_t reason)
266 {
267 	if (!soc || !soc->ops) {
268 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
269 			"%s invalid instance", __func__);
270 		QDF_BUG(0);
271 		return;
272 	}
273 
274 	if (!soc->ops->l_flowctl_ops ||
275 	    !soc->ops->l_flowctl_ops->vdev_pause)
276 		return;
277 
278 	soc->ops->l_flowctl_ops->vdev_pause(vdev, reason);
279 }
280 
281 /**
282  * cdp_fc_vdev_unpause() - resume tx scheduler on vdev
283  * @soc - data path soc handle
284  * @vdev - virtual interface context pointer
285  * @reason - pause reason
286  *
287  * resume tx scheduler on vdev
288  *
289  * return None
290  */
291 static inline void
292 cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, struct cdp_vdev *vdev,
293 		uint32_t reason)
294 {
295 	if (!soc || !soc->ops) {
296 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
297 			"%s invalid instance", __func__);
298 		return;
299 	}
300 
301 	if (!soc->ops->l_flowctl_ops ||
302 	    !soc->ops->l_flowctl_ops->vdev_unpause)
303 		return;
304 
305 	soc->ops->l_flowctl_ops->vdev_unpause(vdev, reason);
306 }
307 #endif /* _CDP_TXRX_FC_LEG_H_ */
308