1 /* 2 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 /** 19 * DOC: This file init/deint functions for dcs module. 20 */ 21 22 #include "wlan_dcs_init_deinit_api.h" 23 #include "../../core/src/wlan_dcs.h" 24 #include "cfg_dcs.h" 25 #include "cfg_ucfg_api.h" 26 27 /** 28 * wlan_dcs_psoc_obj_create_notification() - dcs psoc create handler 29 * @psoc: psoc object 30 * @arg_list: Argument list 31 * 32 * return: QDF_STATUS_SUCCESS for success or error code 33 */ 34 static QDF_STATUS 35 wlan_dcs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, 36 void *arg_list) 37 { 38 QDF_STATUS status; 39 struct dcs_psoc_priv_obj *dcs_psoc_obj; 40 uint8_t loop; 41 42 dcs_psoc_obj = qdf_mem_malloc(sizeof(*dcs_psoc_obj)); 43 44 if (!dcs_psoc_obj) 45 return QDF_STATUS_E_NOMEM; 46 47 for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++) 48 qdf_spinlock_create(&dcs_psoc_obj->dcs_pdev_priv[loop].lock); 49 50 status = wlan_objmgr_psoc_component_obj_attach(psoc, 51 WLAN_UMAC_COMP_DCS, 52 dcs_psoc_obj, 53 QDF_STATUS_SUCCESS); 54 55 if (QDF_IS_STATUS_ERROR(status)) { 56 dcs_err("dcs pdev obj attach failed"); 57 qdf_mem_free(dcs_psoc_obj); 58 return status; 59 } 60 61 dcs_info("dcs psoc object attached"); 62 63 return status; 64 } 65 66 /** 67 * wlan_dcs_psoc_obj_destroy_notification() - dcs psoc destroy handler 68 * @psoc: psoc object 69 * @arg_list: Argument list 70 * 71 * return: QDF_STATUS_SUCCESS for success or error code 72 */ 73 static QDF_STATUS 74 wlan_dcs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, 75 void *arg_list) 76 { 77 QDF_STATUS status; 78 uint8_t loop; 79 struct dcs_psoc_priv_obj *dcs_psoc_obj = 80 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DCS); 81 82 if (!dcs_psoc_obj) { 83 dcs_err("invalid wifi dcs obj"); 84 return QDF_STATUS_E_FAULT; 85 } 86 87 status = wlan_objmgr_psoc_component_obj_detach(psoc, 88 WLAN_UMAC_COMP_DCS, 89 dcs_psoc_obj); 90 for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++) { 91 qdf_timer_free(&dcs_psoc_obj->dcs_pdev_priv[loop]. 92 dcs_disable_timer); 93 qdf_spinlock_destroy(&dcs_psoc_obj->dcs_pdev_priv[loop].lock); 94 } 95 qdf_mem_free(dcs_psoc_obj); 96 97 return status; 98 } 99 100 QDF_STATUS wlan_dcs_init(void) 101 { 102 QDF_STATUS status = QDF_STATUS_SUCCESS; 103 104 status = wlan_objmgr_register_psoc_create_handler( 105 WLAN_UMAC_COMP_DCS, 106 wlan_dcs_psoc_obj_create_notification, 107 NULL); 108 109 if (QDF_IS_STATUS_ERROR(status)) 110 goto err_psoc_create; 111 112 status = wlan_objmgr_register_psoc_destroy_handler( 113 WLAN_UMAC_COMP_DCS, 114 wlan_dcs_psoc_obj_destroy_notification, 115 NULL); 116 117 if (QDF_IS_STATUS_ERROR(status)) 118 goto err_psoc_delete; 119 120 return QDF_STATUS_SUCCESS; 121 122 err_psoc_delete: 123 wlan_objmgr_unregister_psoc_create_handler( 124 WLAN_UMAC_COMP_DCS, 125 wlan_dcs_psoc_obj_create_notification, 126 NULL); 127 err_psoc_create: 128 return status; 129 } 130 131 QDF_STATUS wlan_dcs_deinit(void) 132 { 133 QDF_STATUS status = QDF_STATUS_SUCCESS; 134 135 status = wlan_objmgr_unregister_psoc_create_handler( 136 WLAN_UMAC_COMP_DCS, 137 wlan_dcs_psoc_obj_create_notification, 138 NULL); 139 140 if (QDF_IS_STATUS_ERROR(status)) 141 return QDF_STATUS_E_FAILURE; 142 143 status = wlan_objmgr_unregister_psoc_destroy_handler( 144 WLAN_UMAC_COMP_DCS, 145 wlan_dcs_psoc_obj_destroy_notification, 146 NULL); 147 148 if (QDF_IS_STATUS_ERROR(status)) 149 return QDF_STATUS_E_FAILURE; 150 151 return QDF_STATUS_SUCCESS; 152 } 153 154 QDF_STATUS wlan_dcs_enable(struct wlan_objmgr_psoc *psoc) 155 { 156 return wlan_dcs_attach(psoc); 157 } 158 159 QDF_STATUS wlan_dcs_disable(struct wlan_objmgr_psoc *psoc) 160 { 161 return wlan_dcs_detach(psoc); 162 } 163 164 QDF_STATUS wlan_dcs_psoc_open(struct wlan_objmgr_psoc *psoc) 165 { 166 struct dcs_psoc_priv_obj *dcs_psoc_obj; 167 struct dcs_pdev_priv_obj *dcs_pdev_priv; 168 uint8_t loop; 169 170 if (!psoc) { 171 dcs_err("psoc is NULL"); 172 return QDF_STATUS_E_INVAL; 173 } 174 175 dcs_psoc_obj = wlan_objmgr_psoc_get_comp_private_obj( 176 psoc, WLAN_UMAC_COMP_DCS); 177 if (!dcs_psoc_obj) { 178 dcs_err("dcs psoc private object is NULL"); 179 return QDF_STATUS_E_FAILURE; 180 } 181 182 for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++) { 183 dcs_pdev_priv = &dcs_psoc_obj->dcs_pdev_priv[loop]; 184 dcs_pdev_priv->dcs_host_params.dcs_enable_cfg = 185 cfg_get(psoc, CFG_DCS_ENABLE); 186 dcs_pdev_priv->dcs_host_params.dcs_algorithm_process = false; 187 dcs_pdev_priv->dcs_host_params.dcs_debug = 188 cfg_get(psoc, CFG_DCS_DEBUG); 189 dcs_pdev_priv->dcs_host_params.phy_err_penalty = 190 cfg_get(psoc, CFG_DCS_PHY_ERR_PENALTY); 191 dcs_pdev_priv->dcs_host_params.phy_err_threshold = 192 cfg_get(psoc, CFG_DCS_PHY_ERR_THRESHOLD); 193 dcs_pdev_priv->dcs_host_params.radar_err_threshold = 194 cfg_get(psoc, CFG_DCS_RADAR_ERR_THRESHOLD); 195 dcs_pdev_priv->dcs_host_params.coch_intfr_threshold = 196 cfg_get(psoc, CFG_DCS_COCH_INTFR_THRESHOLD); 197 dcs_pdev_priv->dcs_host_params.user_max_cu = 198 cfg_get(psoc, CFG_DCS_USER_MAX_CU); 199 dcs_pdev_priv->dcs_host_params.intfr_detection_threshold = 200 cfg_get(psoc, CFG_DCS_INTFR_DETECTION_THRESHOLD); 201 dcs_pdev_priv->dcs_host_params.intfr_detection_window = 202 cfg_get(psoc, CFG_DCS_INTFR_DETECTION_WINDOW); 203 dcs_pdev_priv->dcs_host_params.tx_err_threshold = 204 cfg_get(psoc, CFG_DCS_TX_ERR_THRESHOLD); 205 dcs_pdev_priv->dcs_host_params.force_disable_algorithm = 206 cfg_get(psoc, CFG_DCS_DISABLE_ALGORITHM); 207 dcs_pdev_priv->dcs_freq_ctrl_params. 208 disable_threshold_per_5mins = 209 cfg_get(psoc, CFG_DCS_DISABLE_THRESHOLD_PER_5MINS); 210 dcs_pdev_priv->dcs_freq_ctrl_params.restart_delay = 211 cfg_get(psoc, CFG_DCS_RESTART_DELAY); 212 213 qdf_timer_init(NULL, &dcs_pdev_priv->dcs_disable_timer, 214 wlan_dcs_disable_timer_fn, 215 &dcs_pdev_priv->dcs_timer_args, 216 QDF_TIMER_TYPE_WAKE_APPS); 217 } 218 219 return QDF_STATUS_SUCCESS; 220 } 221