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