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