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