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