1 /*
2 * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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 has the dcs dispatcher API implementation which is exposed
20 * to outside of dcs component.
21 */
22
23 #include "wlan_dcs_ucfg_api.h"
24 #include "../../core/src/wlan_dcs.h"
25 #include "wlan_objmgr_vdev_obj.h"
26
ucfg_dcs_register_cb(struct wlan_objmgr_psoc * psoc,dcs_callback cbk,void * arg)27 void ucfg_dcs_register_cb(
28 struct wlan_objmgr_psoc *psoc,
29 dcs_callback cbk,
30 void *arg)
31 {
32 struct dcs_psoc_priv_obj *dcs_psoc_priv;
33
34 dcs_psoc_priv = wlan_objmgr_psoc_get_comp_private_obj(
35 psoc,
36 WLAN_UMAC_COMP_DCS);
37 if (!dcs_psoc_priv) {
38 dcs_err("dcs psoc private object is null");
39 return;
40 }
41
42 dcs_psoc_priv->dcs_cbk.cbk = cbk;
43 dcs_psoc_priv->dcs_cbk.arg = arg;
44 }
45
46 void
ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc * psoc,uint8_t mac_id,uint8_t vdev_id,void (* cb)(uint8_t vdev_id,struct wlan_host_dcs_im_user_stats * stats,int status))47 ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
48 uint8_t mac_id, uint8_t vdev_id,
49 void (*cb)(uint8_t vdev_id,
50 struct wlan_host_dcs_im_user_stats *stats,
51 int status))
52 {
53 struct dcs_pdev_priv_obj *dcs_pdev_priv;
54
55 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
56 if (!dcs_pdev_priv) {
57 dcs_err("dcs pdev private object is null");
58 return;
59 }
60
61 dcs_pdev_priv->requestor_vdev_id = vdev_id;
62 dcs_pdev_priv->user_cb = cb;
63 }
64
ucfg_dcs_register_awgn_cb(struct wlan_objmgr_psoc * psoc,dcs_switch_chan_cb cb)65 QDF_STATUS ucfg_dcs_register_awgn_cb(struct wlan_objmgr_psoc *psoc,
66 dcs_switch_chan_cb cb)
67 {
68 struct dcs_psoc_priv_obj *dcs_psoc_priv;
69
70 dcs_psoc_priv =
71 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DCS);
72 if (!dcs_psoc_priv) {
73 dcs_err("dcs psoc private object is null");
74 return QDF_STATUS_E_INVAL;
75 }
76
77 dcs_psoc_priv->switch_chan_cb = cb;
78 return QDF_STATUS_SUCCESS;
79 }
80
ucfg_dcs_register_afc_sel_chan_cb(struct wlan_objmgr_psoc * psoc,dcs_afc_select_chan_cb cb,void * arg)81 QDF_STATUS ucfg_dcs_register_afc_sel_chan_cb(struct wlan_objmgr_psoc *psoc,
82 dcs_afc_select_chan_cb cb,
83 void *arg)
84 {
85 struct dcs_psoc_priv_obj *dcs_psoc_priv;
86
87 dcs_psoc_priv =
88 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DCS);
89 if (!dcs_psoc_priv) {
90 dcs_err("dcs psoc private object is null");
91 return QDF_STATUS_E_INVAL;
92 }
93
94 dcs_psoc_priv->afc_sel_chan_cbk.cbk = cb;
95 dcs_psoc_priv->afc_sel_chan_cbk.arg = arg;
96 return QDF_STATUS_SUCCESS;
97 }
98
99 QDF_STATUS
ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc * psoc,uint32_t mac_id,bool is_host_pdev_id)100 ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc,
101 uint32_t mac_id,
102 bool is_host_pdev_id)
103 {
104 return wlan_dcs_cmd_send(psoc, mac_id, is_host_pdev_id);
105 }
106
ucfg_config_dcs_enable(struct wlan_objmgr_psoc * psoc,uint32_t mac_id,uint8_t interference_type)107 void ucfg_config_dcs_enable(struct wlan_objmgr_psoc *psoc,
108 uint32_t mac_id,
109 uint8_t interference_type)
110 {
111 struct dcs_pdev_priv_obj *dcs_pdev_priv;
112
113 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
114 if (!dcs_pdev_priv) {
115 dcs_err("dcs pdev private object is null");
116 return;
117 }
118
119 dcs_pdev_priv->dcs_host_params.dcs_enable |= interference_type;
120 }
121
ucfg_config_dcs_disable(struct wlan_objmgr_psoc * psoc,uint32_t mac_id,uint8_t interference_type)122 void ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc,
123 uint32_t mac_id,
124 uint8_t interference_type)
125 {
126 struct dcs_pdev_priv_obj *dcs_pdev_priv;
127
128 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
129 if (!dcs_pdev_priv) {
130 dcs_err("dcs pdev private object is null");
131 return;
132 }
133
134 dcs_pdev_priv->dcs_host_params.dcs_enable &= (~interference_type);
135 }
136
ucfg_get_dcs_enable(struct wlan_objmgr_psoc * psoc,uint8_t mac_id)137 uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t mac_id)
138 {
139 struct dcs_pdev_priv_obj *dcs_pdev_priv;
140 uint8_t enable = 0;
141
142 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
143 if (!dcs_pdev_priv) {
144 dcs_err("dcs pdev private object is null");
145 return 0;
146 }
147
148 if (dcs_pdev_priv->dcs_host_params.dcs_enable_cfg)
149 enable = dcs_pdev_priv->dcs_host_params.dcs_enable;
150
151 return enable;
152 }
153
ucfg_dcs_clear(struct wlan_objmgr_psoc * psoc,uint32_t mac_id)154 void ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t mac_id)
155 {
156 wlan_dcs_clear(psoc, mac_id);
157 }
158
ucfg_config_dcs_event_data(struct wlan_objmgr_psoc * psoc,uint32_t mac_id,bool dcs_algorithm_process)159 void ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t mac_id,
160 bool dcs_algorithm_process)
161 {
162 wlan_dcs_set_algorithm_process(psoc, mac_id, dcs_algorithm_process);
163 }
164
ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc * psoc,uint8_t mac_id)165 void ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t mac_id)
166 {
167 struct dcs_pdev_priv_obj *dcs_pdev_priv;
168 struct wlan_host_dcs_im_user_stats *user_stats;
169
170 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
171 if (!dcs_pdev_priv) {
172 dcs_err("dcs pdev private object is null");
173 return;
174 }
175
176 wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
177 dcs_pdev_priv->dcs_host_params.user_request_count = 0;
178 dcs_pdev_priv->dcs_host_params.notify_user = 0;
179 user_stats = &dcs_pdev_priv->dcs_im_stats.user_dcs_im_stats;
180 user_stats->cycle_count = 0;
181 user_stats->rxclr_count = 0;
182 user_stats->rx_frame_count = 0;
183 user_stats->my_bss_rx_cycle_count = 0;
184 user_stats->max_rssi = 0;
185 user_stats->min_rssi = 0;
186 wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
187 }
188
ucfg_dcs_set_user_request(struct wlan_objmgr_psoc * psoc,uint8_t mac_id,uint32_t user_request_count)189 void ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
190 uint32_t user_request_count)
191 {
192 struct dcs_pdev_priv_obj *dcs_pdev_priv;
193
194 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
195 if (!dcs_pdev_priv) {
196 dcs_err("dcs pdev private object is null");
197 return;
198 }
199
200 wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
201 dcs_pdev_priv->dcs_host_params.user_request_count = user_request_count;
202 wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
203 }
204
ucfg_dcs_get_ch_util(struct wlan_objmgr_psoc * psoc,uint8_t mac_id,struct wlan_host_dcs_ch_util_stats * dcs_stats)205 QDF_STATUS ucfg_dcs_get_ch_util(struct wlan_objmgr_psoc *psoc, uint8_t mac_id,
206 struct wlan_host_dcs_ch_util_stats *dcs_stats)
207 {
208 struct dcs_pdev_priv_obj *dcs_pdev_priv;
209
210 dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, mac_id);
211 if (!dcs_pdev_priv) {
212 dcs_err("dcs pdev private object is null");
213 return QDF_STATUS_E_INVAL;
214 }
215
216 wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
217 qdf_mem_copy(dcs_stats,
218 &dcs_pdev_priv->dcs_im_stats.dcs_ch_util_im_stats,
219 sizeof(*dcs_stats));
220 wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
221
222 return QDF_STATUS_SUCCESS;
223 }
224
225 #ifdef DCS_INTERFERENCE_DETECTION
226 QDF_STATUS
ucfg_dcs_switch_chan(struct wlan_objmgr_vdev * vdev,qdf_freq_t tgt_freq,enum phy_ch_width tgt_width)227 ucfg_dcs_switch_chan(struct wlan_objmgr_vdev *vdev, qdf_freq_t tgt_freq,
228 enum phy_ch_width tgt_width)
229 {
230 return wlan_dcs_switch_chan(vdev, tgt_freq, tgt_width);
231 }
232 #endif
233