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