1 /* 2 * Copyright (c) 2016-2019,2021 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 #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 * Returns: 0 for success 40 */ 41 static inline int 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 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 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 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 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 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 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 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 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 avaialbe 182 */ 183 static inline bool 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 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 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 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 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