1 /* 2 * Copyright (c) 2019-2020 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 * Layer b/w umac and target_if (ol) txops 21 * It contains wrapers for txops 22 */ 23 24 #include <wlan_cfr_tgt_api.h> 25 #include <wlan_cfr_utils_api.h> 26 #include <target_type.h> 27 #include <cfr_defs_i.h> 28 29 uint32_t tgt_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head, 30 size_t hlen, void *data, size_t dlen, void *tail, 31 size_t tlen) 32 { 33 struct pdev_cfr *pa; 34 uint32_t status; 35 36 pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); 37 38 if (pa == NULL) { 39 cfr_err("pdev_cfr is NULL\n"); 40 return -1; 41 } 42 43 if (head) 44 status = cfr_streamfs_write(pa, (const void *)head, hlen); 45 46 if (data) 47 status = cfr_streamfs_write(pa, (const void *)data, dlen); 48 49 if (tail) 50 status = cfr_streamfs_write(pa, (const void *)tail, tlen); 51 52 53 /* finalise the write */ 54 status = cfr_streamfs_flush(pa); 55 56 return status; 57 } 58 59 void tgt_cfr_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value) 60 { 61 struct psoc_cfr *cfr_sc; 62 63 if (psoc == NULL) 64 return; 65 66 cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 67 WLAN_UMAC_COMP_CFR); 68 if (cfr_sc == NULL) 69 return; 70 71 cfr_sc->is_cfr_capable = !!value; 72 cfr_debug("CFR: FW support advert=%d", cfr_sc->is_cfr_capable); 73 } 74 75 static inline struct wlan_lmac_if_cfr_tx_ops * 76 wlan_psoc_get_cfr_txops(struct wlan_objmgr_psoc *psoc) 77 { 78 struct wlan_lmac_if_tx_ops *tx_ops; 79 80 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 81 if (!tx_ops) { 82 cfr_err("tx_ops is NULL"); 83 return NULL; 84 } 85 return &tx_ops->cfr_tx_ops; 86 } 87 88 int tgt_cfr_get_target_type(struct wlan_objmgr_psoc *psoc) 89 { 90 uint32_t target_type = 0; 91 struct wlan_lmac_if_target_tx_ops *target_type_tx_ops; 92 struct wlan_lmac_if_tx_ops *tx_ops; 93 94 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 95 if (!tx_ops) { 96 cfr_err("tx_ops is NULL"); 97 return target_type; 98 } 99 target_type_tx_ops = &tx_ops->target_tx_ops; 100 101 if (target_type_tx_ops->tgt_get_tgt_type) 102 target_type = target_type_tx_ops->tgt_get_tgt_type(psoc); 103 104 return target_type; 105 } 106 107 QDF_STATUS tgt_cfr_init_pdev(struct wlan_objmgr_pdev *pdev) 108 { 109 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 110 QDF_STATUS status = QDF_STATUS_SUCCESS; 111 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 112 113 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 114 115 if (cfr_tx_ops->cfr_init_pdev) 116 status = cfr_tx_ops->cfr_init_pdev(psoc, pdev); 117 118 if (QDF_IS_STATUS_ERROR(status)) 119 cfr_err("Error occurred with exit code %d\n", status); 120 121 return status; 122 } 123 124 QDF_STATUS tgt_cfr_deinit_pdev(struct wlan_objmgr_pdev *pdev) 125 { 126 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 127 QDF_STATUS status = QDF_STATUS_SUCCESS; 128 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 129 130 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 131 132 if (cfr_tx_ops->cfr_deinit_pdev) 133 status = cfr_tx_ops->cfr_deinit_pdev(psoc, pdev); 134 135 if (QDF_IS_STATUS_ERROR(status)) 136 cfr_err("Error occurred with exit code %d\n", status); 137 138 return status; 139 } 140 141 int tgt_cfr_start_capture(struct wlan_objmgr_pdev *pdev, 142 struct wlan_objmgr_peer *peer, 143 struct cfr_capture_params *cfr_params) 144 { 145 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 146 int status = 0; 147 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 148 149 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 150 151 if (cfr_tx_ops->cfr_start_capture) 152 status = cfr_tx_ops->cfr_start_capture(pdev, peer, cfr_params); 153 154 if (status != 0) 155 cfr_err("Error occurred with exit code %d\n", status); 156 157 return status; 158 } 159 160 int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, 161 struct wlan_objmgr_peer *peer) 162 { 163 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 164 int status = 0; 165 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 166 167 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 168 169 if (cfr_tx_ops->cfr_stop_capture) 170 status = cfr_tx_ops->cfr_stop_capture(pdev, peer); 171 172 if (status != 0) 173 cfr_err("Error occurred with exit code %d\n", status); 174 175 return status; 176 } 177 178 int 179 tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer) 180 { 181 int status = 0; 182 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 183 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 184 185 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 186 187 if (cfr_tx_ops->cfr_enable_cfr_timer) 188 status = cfr_tx_ops->cfr_enable_cfr_timer(pdev, cfr_timer); 189 190 if (status != 0) 191 cfr_err("Error occurred with exit code %d\n", status); 192 193 return status; 194 } 195 196 #ifdef WLAN_ENH_CFR_ENABLE 197 QDF_STATUS 198 tgt_cfr_config_rcc(struct wlan_objmgr_pdev *pdev, 199 struct cfr_rcc_param *rcc_param) 200 { 201 QDF_STATUS status = QDF_STATUS_SUCCESS; 202 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 203 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 204 205 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 206 207 if (cfr_tx_ops->cfr_config_rcc) 208 status = cfr_tx_ops->cfr_config_rcc(pdev, rcc_param); 209 210 if (status != QDF_STATUS_SUCCESS) 211 cfr_err("Error occurred with exit code %d\n", status); 212 213 return status; 214 } 215 216 void tgt_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev) 217 { 218 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 219 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 220 221 if (!psoc) { 222 cfr_err("Invalid PSOC: Flush LUT Timer cannot be started\n"); 223 return; 224 } 225 226 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 227 228 if (cfr_tx_ops->cfr_start_lut_timer) 229 cfr_tx_ops->cfr_start_lut_timer(pdev); 230 } 231 232 void tgt_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev) 233 { 234 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 235 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 236 237 if (!psoc) { 238 cfr_err("Invalid PSOC: Flush LUT Timer cannot be stopped\n"); 239 return; 240 } 241 242 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 243 244 if (cfr_tx_ops->cfr_stop_lut_timer) 245 cfr_tx_ops->cfr_stop_lut_timer(pdev); 246 } 247 248 void tgt_cfr_default_ta_ra_cfg(struct wlan_objmgr_pdev *pdev, 249 struct cfr_rcc_param *rcc_param, 250 bool allvalid, uint16_t reset_cfg) 251 { 252 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 253 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 254 255 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 256 257 if (cfr_tx_ops->cfr_default_ta_ra_cfg) 258 cfr_tx_ops->cfr_default_ta_ra_cfg(rcc_param, 259 allvalid, reset_cfg); 260 } 261 262 void tgt_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev) 263 { 264 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 265 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 266 267 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 268 269 if (cfr_tx_ops->cfr_dump_lut_enh) 270 cfr_tx_ops->cfr_dump_lut_enh(pdev); 271 } 272 273 void tgt_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf) 274 { 275 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 276 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 277 278 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 279 280 if (cfr_tx_ops->cfr_rx_tlv_process) 281 cfr_tx_ops->cfr_rx_tlv_process(pdev, nbuf); 282 } 283 284 void tgt_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev) 285 { 286 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 287 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 288 289 if (!psoc) { 290 cfr_err("Invalid PSOC:Cannot update global config.\n"); 291 return; 292 } 293 294 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 295 296 if (cfr_tx_ops->cfr_update_global_cfg) 297 cfr_tx_ops->cfr_update_global_cfg(pdev); 298 } 299 300 QDF_STATUS tgt_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, 301 bool is_subscribe) 302 { 303 struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; 304 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); 305 306 if (!psoc) { 307 cfr_err("Invalid psoc\n"); 308 return QDF_STATUS_E_INVAL; 309 } 310 311 cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); 312 313 if (cfr_tx_ops->cfr_subscribe_ppdu_desc) 314 return cfr_tx_ops->cfr_subscribe_ppdu_desc(pdev, 315 is_subscribe); 316 317 return QDF_STATUS_SUCCESS; 318 } 319 320 QDF_STATUS 321 tgt_cfr_capture_count_support_set(struct wlan_objmgr_psoc *psoc, 322 uint32_t value) 323 { 324 struct psoc_cfr *cfr_sc; 325 326 if (!psoc) { 327 cfr_err("CFR: NULL PSOC!!"); 328 return QDF_STATUS_E_INVAL; 329 } 330 331 cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 332 WLAN_UMAC_COMP_CFR); 333 334 if (!cfr_sc) { 335 cfr_err("Failed to get CFR component priv obj!!"); 336 return QDF_STATUS_E_INVAL; 337 } 338 339 cfr_sc->is_cap_interval_mode_sel_support = !!value; 340 cfr_debug("CFR: cap_interval_mode_sel_support is %s\n", 341 (cfr_sc->is_cap_interval_mode_sel_support) ? 342 "enabled" : 343 "disabled"); 344 345 return QDF_STATUS_SUCCESS; 346 } 347 348 QDF_STATUS 349 tgt_cfr_mo_marking_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value) 350 { 351 struct psoc_cfr *cfr_sc; 352 353 if (!psoc) { 354 cfr_err("CFR: NULL PSOC!!"); 355 return QDF_STATUS_E_INVAL; 356 } 357 358 cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc, 359 WLAN_UMAC_COMP_CFR); 360 if (!cfr_sc) { 361 cfr_err("Failed to get CFR component priv obj!!"); 362 return QDF_STATUS_E_INVAL; 363 } 364 365 cfr_sc->is_mo_marking_support = !!value; 366 cfr_debug("CFR: mo_marking_support is %s\n", 367 (cfr_sc->is_mo_marking_support) ? "enabled" : "disabled"); 368 369 return QDF_STATUS_SUCCESS; 370 } 371 #else 372 QDF_STATUS 373 tgt_cfr_capture_count_support_set(struct wlan_objmgr_psoc *psoc, 374 uint32_t value) 375 { 376 return QDF_STATUS_E_NOSUPPORT; 377 } 378 379 QDF_STATUS 380 tgt_cfr_mo_marking_support_set(struct wlan_objmgr_psoc *psoc, 381 uint32_t value) 382 { 383 return QDF_STATUS_E_NOSUPPORT; 384 } 385 #endif 386