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