1 /* 2 * Copyright (c) 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 * DOC : target_if_cfr_6490.c 21 * 22 * Target interface of CFR for QCA6490 implementation 23 * 24 */ 25 26 #include <cdp_txrx_ctrl.h> 27 #include "target_if_cfr.h" 28 #include <qdf_nbuf.h> 29 #include "wlan_cfr_utils_api.h" 30 #include "target_if_cfr_6490.h" 31 #include "target_if_cfr_enh.h" 32 #include "init_deinit_lmac.h" 33 #include "cfg_ucfg_api.h" 34 #include "cfr_cfg.h" 35 36 #ifdef WLAN_ENH_CFR_ENABLE 37 #ifdef CFR_USE_FIXED_FOLDER 38 static wdi_event_subscribe g_cfr_subscribe; 39 40 static void target_cfr_callback(void *pdev_obj, enum WDI_EVENT event, 41 void *data, u_int16_t peer_id, 42 uint32_t status) 43 { 44 struct wlan_objmgr_pdev *pdev; 45 qdf_nbuf_t nbuf = (qdf_nbuf_t)data; 46 qdf_nbuf_t data_clone; 47 48 pdev = (struct wlan_objmgr_pdev *)pdev_obj; 49 if (qdf_unlikely((!pdev || !data))) { 50 cfr_err("Invalid pdev %pK or data %pK for event %d", 51 pdev, data, event); 52 qdf_nbuf_free(nbuf); 53 return; 54 } 55 56 if (event != WDI_EVENT_RX_PPDU_DESC) { 57 cfr_debug("event is %d", event); 58 qdf_nbuf_free(nbuf); 59 return; 60 } 61 62 data_clone = qdf_nbuf_clone(nbuf); 63 if (data_clone) 64 wlan_cfr_rx_tlv_process(pdev, (void *)data_clone); 65 66 qdf_nbuf_free(nbuf); 67 } 68 69 QDF_STATUS 70 target_if_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev, 71 bool is_subscribe) 72 { 73 ol_txrx_soc_handle soc; 74 struct wlan_objmgr_psoc *psoc; 75 struct pdev_cfr *pcfr; 76 77 if (!pdev) { 78 cfr_err("Null pdev"); 79 return QDF_STATUS_E_INVAL; 80 } 81 82 pcfr = wlan_objmgr_pdev_get_comp_private_obj( 83 pdev, WLAN_UMAC_COMP_CFR); 84 if (!pcfr) { 85 cfr_err("pcfr is NULL"); 86 return QDF_STATUS_E_INVAL; 87 } 88 89 psoc = wlan_pdev_get_psoc(pdev); 90 if (!psoc) { 91 cfr_err("Null psoc"); 92 return QDF_STATUS_E_INVAL; 93 } 94 95 soc = wlan_psoc_get_dp_handle(psoc); 96 if (!soc) { 97 cfr_err("Null soc"); 98 return QDF_STATUS_E_INVAL; 99 } 100 101 g_cfr_subscribe.callback = target_cfr_callback; 102 g_cfr_subscribe.context = pdev; 103 cdp_set_cfr_rcc(soc, 0, is_subscribe); 104 cdp_enable_mon_reap_timer(soc, 0, is_subscribe); 105 if (is_subscribe) { 106 if (cdp_wdi_event_sub(soc, 0, &g_cfr_subscribe, 107 WDI_EVENT_RX_PPDU_DESC)) { 108 cfr_err("wdi event sub fail"); 109 return QDF_STATUS_E_FAILURE; 110 } 111 } else { 112 if (cdp_wdi_event_unsub(soc, 0, &g_cfr_subscribe, 113 WDI_EVENT_RX_PPDU_DESC)) { 114 cfr_err("wdi event unsub fail"); 115 return QDF_STATUS_E_FAILURE; 116 } 117 } 118 119 return QDF_STATUS_SUCCESS; 120 } 121 #endif 122 #endif 123 124 125