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