xref: /wlan-dirver/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_legacy.h (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2016-2019,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 /**
21  * @file cdp_txrx_flow_ctrl_legacy.h
22  * @brief Define the host data path legacy flow control API
23  * functions
24  */
25 #ifndef _CDP_TXRX_FC_LEG_H_
26 #define _CDP_TXRX_FC_LEG_H_
27 #include <cdp_txrx_mob_def.h>
28 #include "cdp_txrx_handle.h"
29 #include <cdp_txrx_cmn.h>
30 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
31 
32 /**
33  * cdp_hl_fc_register() - Register HL flow control callback.
34  * @soc: data path soc handle
35  * @pdev_id: datapath pdev identifier
36  * @flowcontrol: callback function pointer to stop/start OS netdev queues
37  *
38  * Register flow control callback.
39  *
40  * Returns: 0 for success
41  */
42 static inline int
43 cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
44 		   tx_pause_callback flowcontrol)
45 {
46 	if (!soc || !soc->ops) {
47 		dp_cdp_debug("invalid instance");
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 		dp_cdp_debug("invalid instance");
124 		QDF_BUG(0);
125 		return 0;
126 	}
127 
128 	if (!soc->ops->l_flowctl_ops ||
129 	    !soc->ops->l_flowctl_ops->register_tx_flow_control)
130 		return 0;
131 
132 	return soc->ops->l_flowctl_ops->register_tx_flow_control(
133 			soc, vdev_id, flowcontrol, osif_fc_ctx,
134 			flow_control_is_pause);
135 }
136 #else
137 static inline int
138 cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
139 		ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
140 		ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
141 {
142 	return 0;
143 }
144 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
145 /**
146  * cdp_fc_deregister() - remove flow control instance
147  * @soc - data path soc handle
148  * @vdev_id - virtual interface id to register flow control
149  *
150  * remove flow control instance
151  *
152  * return 0 success
153  */
154 static inline int
155 cdp_fc_deregister(ol_txrx_soc_handle soc, uint8_t vdev_id)
156 {
157 	if (!soc || !soc->ops) {
158 		dp_cdp_debug("invalid instance");
159 		QDF_BUG(0);
160 		return 0;
161 	}
162 
163 	if (!soc->ops->l_flowctl_ops ||
164 	    !soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb)
165 		return 0;
166 
167 	return soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb(
168 			soc, vdev_id);
169 }
170 
171 /**
172  * cdp_fc_get_tx_resource() - get data path resource count
173  * @soc: data path soc handle
174  * @pdev_id: datapath pdev ID
175  * @peer_addr: peer mac address
176  * @low_watermark: low resource threshold
177  * @high_watermark_offset: high resource threshold
178  *
179  * get data path resource count
180  *
181  * return true enough data path resource available
182  *        false resource is not available
183  */
184 static inline bool
185 cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t pdev_id,
186 		       struct qdf_mac_addr peer_addr,
187 		       unsigned int low_watermark,
188 		       unsigned int high_watermark_offset)
189 {
190 	if (!soc || !soc->ops) {
191 		dp_cdp_debug("invalid instance");
192 		QDF_BUG(0);
193 		return false;
194 	}
195 
196 	if (!soc->ops->l_flowctl_ops ||
197 	    !soc->ops->l_flowctl_ops->get_tx_resource)
198 		return false;
199 
200 	return soc->ops->l_flowctl_ops->get_tx_resource(soc, pdev_id, peer_addr,
201 							low_watermark,
202 							high_watermark_offset);
203 }
204 
205 /**
206  * cdp_fc_ll_set_tx_pause_q_depth() - set pause queue depth
207  * @soc - data path soc handle
208  * @vdev_id - virtual interface id to register flow control
209  * @pause_q_depth - pending tx queue delth
210  *
211  * set pause queue depth
212  *
213  * return 0 success
214  */
215 static inline int
216 cdp_fc_ll_set_tx_pause_q_depth(ol_txrx_soc_handle soc,
217 		uint8_t vdev_id, int pause_q_depth)
218 {
219 	if (!soc || !soc->ops) {
220 		dp_cdp_debug("invalid instance");
221 		QDF_BUG(0);
222 		return 0;
223 	}
224 
225 	if (!soc->ops->l_flowctl_ops ||
226 	    !soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth)
227 		return 0;
228 
229 	return soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth(
230 			soc, vdev_id, pause_q_depth);
231 
232 }
233 
234 /**
235  * cdp_fc_vdev_flush() - flush tx queue
236  * @soc: data path soc handle
237  * @vdev_id: id of vdev
238  *
239  * flush tx queue
240  *
241  * return None
242  */
243 static inline void
244 cdp_fc_vdev_flush(ol_txrx_soc_handle soc, uint8_t vdev_id)
245 {
246 	if (!soc || !soc->ops) {
247 		dp_cdp_debug("invalid instance");
248 		QDF_BUG(0);
249 		return;
250 	}
251 
252 	if (!soc->ops->l_flowctl_ops ||
253 	    !soc->ops->l_flowctl_ops->vdev_flush)
254 		return;
255 
256 	soc->ops->l_flowctl_ops->vdev_flush(soc, vdev_id);
257 }
258 
259 /**
260  * cdp_fc_vdev_pause() - pause tx scheduler on vdev
261  * @soc: data path soc handle
262  * @vdev_id: id of vdev
263  * @reason: pause reason
264  * @pause_type: type of pause
265  *
266  * pause tx scheduler on vdev
267  *
268  * return None
269  */
270 static inline void
271 cdp_fc_vdev_pause(ol_txrx_soc_handle soc, uint8_t vdev_id,
272 		  uint32_t reason, uint32_t pause_type)
273 {
274 	if (!soc || !soc->ops) {
275 		dp_cdp_debug("invalid instance");
276 		QDF_BUG(0);
277 		return;
278 	}
279 
280 	if (!soc->ops->l_flowctl_ops ||
281 	    !soc->ops->l_flowctl_ops->vdev_pause)
282 		return;
283 
284 	soc->ops->l_flowctl_ops->vdev_pause(soc, vdev_id, reason, pause_type);
285 }
286 
287 /**
288  * cdp_fc_vdev_unpause() - resume tx scheduler on vdev
289  * @soc: data path soc handle
290  * @vdev_id: id of vdev
291  * @reason: pause reason
292  * @pause_type: type of pause
293  *
294  * resume tx scheduler on vdev
295  *
296  * return None
297  */
298 static inline void
299 cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, uint8_t vdev_id,
300 		    uint32_t reason, uint32_t pause_type)
301 {
302 	if (!soc || !soc->ops) {
303 		dp_cdp_debug("invalid instance");
304 		return;
305 	}
306 
307 	if (!soc->ops->l_flowctl_ops ||
308 	    !soc->ops->l_flowctl_ops->vdev_unpause)
309 		return;
310 
311 	soc->ops->l_flowctl_ops->vdev_unpause(soc, vdev_id, reason,
312 					      pause_type);
313 }
314 #endif /* _CDP_TXRX_FC_LEG_H_ */
315