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
wlan_dcs_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)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
wlan_dcs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)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
wlan_dcs_init(void)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
wlan_dcs_deinit(void)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
wlan_dcs_enable(struct wlan_objmgr_psoc * psoc)154 QDF_STATUS wlan_dcs_enable(struct wlan_objmgr_psoc *psoc)
155 {
156 return wlan_dcs_attach(psoc);
157 }
158
wlan_dcs_disable(struct wlan_objmgr_psoc * psoc)159 QDF_STATUS wlan_dcs_disable(struct wlan_objmgr_psoc *psoc)
160 {
161 return wlan_dcs_detach(psoc);
162 }
163
wlan_dcs_psoc_open(struct wlan_objmgr_psoc * psoc)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