1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <wlan_cfr_utils_api.h>
20 #include <wlan_cfr_tgt_api.h>
21 #include <qdf_module.h>
22 #include <cfr_defs_i.h>
23 #include <wlan_objmgr_global_obj.h>
24 #include <wlan_objmgr_pdev_obj.h>
25 
wlan_cfr_init(void)26 QDF_STATUS wlan_cfr_init(void)
27 {
28 	if (wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_CFR,
29 				wlan_cfr_psoc_obj_create_handler, NULL)
30 				!= QDF_STATUS_SUCCESS) {
31 		return QDF_STATUS_E_FAILURE;
32 	}
33 	if (wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_CFR,
34 				wlan_cfr_psoc_obj_destroy_handler, NULL)
35 				!= QDF_STATUS_SUCCESS) {
36 		return QDF_STATUS_E_FAILURE;
37 	}
38 	if (wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_CFR,
39 				wlan_cfr_pdev_obj_create_handler, NULL)
40 				!= QDF_STATUS_SUCCESS) {
41 		return QDF_STATUS_E_FAILURE;
42 	}
43 	if (wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_CFR,
44 				wlan_cfr_pdev_obj_destroy_handler, NULL)
45 				!= QDF_STATUS_SUCCESS) {
46 		return QDF_STATUS_E_FAILURE;
47 	}
48 	if (wlan_objmgr_register_peer_create_handler(WLAN_UMAC_COMP_CFR,
49 				wlan_cfr_peer_obj_create_handler, NULL)
50 				!= QDF_STATUS_SUCCESS) {
51 		return QDF_STATUS_E_FAILURE;
52 	}
53 	if (wlan_objmgr_register_peer_destroy_handler(WLAN_UMAC_COMP_CFR,
54 				wlan_cfr_peer_obj_destroy_handler, NULL)
55 				!= QDF_STATUS_SUCCESS) {
56 		return QDF_STATUS_E_FAILURE;
57 	}
58 
59 	return QDF_STATUS_SUCCESS;
60 }
61 
wlan_cfr_deinit(void)62 QDF_STATUS wlan_cfr_deinit(void)
63 {
64 	if (wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_CFR,
65 				wlan_cfr_psoc_obj_create_handler, NULL)
66 				!= QDF_STATUS_SUCCESS) {
67 		return QDF_STATUS_E_FAILURE;
68 	}
69 	if (wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_CFR,
70 				wlan_cfr_psoc_obj_destroy_handler, NULL)
71 				!= QDF_STATUS_SUCCESS) {
72 		return QDF_STATUS_E_FAILURE;
73 	}
74 	if (wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CFR,
75 				wlan_cfr_pdev_obj_create_handler, NULL)
76 				!= QDF_STATUS_SUCCESS) {
77 		return QDF_STATUS_E_FAILURE;
78 	}
79 	if (wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_CFR,
80 				wlan_cfr_pdev_obj_destroy_handler, NULL)
81 				!= QDF_STATUS_SUCCESS) {
82 		return QDF_STATUS_E_FAILURE;
83 	}
84 	if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CFR,
85 				wlan_cfr_peer_obj_create_handler, NULL)
86 				!= QDF_STATUS_SUCCESS) {
87 		return QDF_STATUS_E_FAILURE;
88 	}
89 	if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CFR,
90 				wlan_cfr_peer_obj_destroy_handler, NULL)
91 				!= QDF_STATUS_SUCCESS) {
92 		return QDF_STATUS_E_FAILURE;
93 	}
94 	return QDF_STATUS_SUCCESS;
95 }
96 
wlan_cfr_pdev_open(struct wlan_objmgr_pdev * pdev)97 QDF_STATUS wlan_cfr_pdev_open(struct wlan_objmgr_pdev *pdev)
98 {
99 	QDF_STATUS status;
100 
101 	if (wlan_cfr_is_feature_disabled(pdev)) {
102 		cfr_err("cfr is disabled");
103 		return QDF_STATUS_COMP_DISABLED;
104 	}
105 	/* chip specific init */
106 	status = tgt_cfr_init_pdev(pdev);
107 
108 	if (status != QDF_STATUS_SUCCESS) {
109 		cfr_err("tgt_cfr_init_pdev failed with %d\n", status);
110 		return QDF_STATUS_SUCCESS;
111 	}
112 
113 	/* RealyFS init */
114 	status = cfr_streamfs_init(pdev);
115 
116 	if (status != QDF_STATUS_SUCCESS) {
117 		cfr_err("cfr_streamfs_init failed with %d\n", status);
118 		return QDF_STATUS_SUCCESS;
119 	}
120 
121 	return QDF_STATUS_SUCCESS;
122 }
123 
wlan_cfr_pdev_close(struct wlan_objmgr_pdev * pdev)124 QDF_STATUS wlan_cfr_pdev_close(struct wlan_objmgr_pdev *pdev)
125 {
126 	QDF_STATUS status = QDF_STATUS_SUCCESS;
127 
128 	if (wlan_cfr_is_feature_disabled(pdev)) {
129 		cfr_err("cfr is disabled");
130 		return QDF_STATUS_COMP_DISABLED;
131 	}
132 	/*
133 	 * DBR does not have close as of now;
134 	 * but this is getting added as part for new gerrit
135 	 * Once we have that support we will add it.
136 	 */
137 	status = cfr_streamfs_remove(pdev);
138 
139 	return status;
140 }
141 
cfr_initialize_pdev(struct wlan_objmgr_pdev * pdev)142 QDF_STATUS cfr_initialize_pdev(struct wlan_objmgr_pdev *pdev)
143 {
144 	QDF_STATUS status = QDF_STATUS_SUCCESS;
145 
146 	if (wlan_cfr_is_feature_disabled(pdev)) {
147 		cfr_err("cfr is disabled");
148 		return QDF_STATUS_COMP_DISABLED;
149 	}
150 
151 	/* chip specific init */
152 
153 	status = tgt_cfr_init_pdev(pdev);
154 
155 	if (status != QDF_STATUS_SUCCESS)
156 		cfr_err("cfr_initialize_pdev status=%d\n", status);
157 
158 	return status;
159 }
160 qdf_export_symbol(cfr_initialize_pdev);
161 
cfr_deinitialize_pdev(struct wlan_objmgr_pdev * pdev)162 QDF_STATUS cfr_deinitialize_pdev(struct wlan_objmgr_pdev *pdev)
163 {
164 	QDF_STATUS status = QDF_STATUS_SUCCESS;
165 
166 	if (wlan_cfr_is_feature_disabled(pdev)) {
167 		cfr_err("cfr is disabled");
168 		return QDF_STATUS_COMP_DISABLED;
169 	}
170 
171 	/* chip specific deinit */
172 
173 	status = tgt_cfr_deinit_pdev(pdev);
174 
175 	if (status != QDF_STATUS_SUCCESS)
176 		cfr_err("cfr_deinitialize_pdev status=%d\n", status);
177 
178 	return status;
179 }
180 qdf_export_symbol(cfr_deinitialize_pdev);
181 
count_set_bits(unsigned long value)182 uint8_t count_set_bits(unsigned long value)
183 {
184 	uint8_t count = 0;
185 
186 	while (value) {
187 		value &= (value - 1);
188 		count++;
189 	}
190 
191 	return count;
192 }
193 
194 qdf_export_symbol(count_set_bits);
195 
196 #ifdef WLAN_ENH_CFR_ENABLE
wlan_cfr_rx_tlv_process(struct wlan_objmgr_pdev * pdev,void * nbuf)197 void wlan_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
198 {
199 	tgt_cfr_rx_tlv_process(pdev, nbuf);
200 }
201 
202 qdf_export_symbol(wlan_cfr_rx_tlv_process);
203 #endif
204 
wlan_cfr_is_feature_disabled(struct wlan_objmgr_pdev * pdev)205 bool wlan_cfr_is_feature_disabled(struct wlan_objmgr_pdev *pdev)
206 {
207 	if (!pdev) {
208 		cfr_err("PDEV is NULL!");
209 		return true;
210 	}
211 
212 	return (wlan_pdev_nif_feat_ext_cap_get(pdev, WLAN_PDEV_FEXT_CFR_EN) ?
213 		false : true);
214 }
215 
216 qdf_export_symbol(wlan_cfr_is_feature_disabled);
217