1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2015,2017-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name * above copyright notice and this permission notice appear in all
8*5113495bSYour Name * copies.
9*5113495bSYour Name *
10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name */
19*5113495bSYour Name
20*5113495bSYour Name #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION
21*5113495bSYour Name #include "target_if_spectral.h"
22*5113495bSYour Name #include "target_if_spectral_sim.h"
23*5113495bSYour Name #include "target_if_spectral_sim_int.h"
24*5113495bSYour Name #include "_ieee80211.h"
25*5113495bSYour Name #include "ieee80211_api.h"
26*5113495bSYour Name #include "ieee80211_defines.h"
27*5113495bSYour Name #include "qdf_types.h"
28*5113495bSYour Name #include "ieee80211_var.h"
29*5113495bSYour Name #include <wlan_mlme_dispatcher.h>
30*5113495bSYour Name #include <qdf_module.h>
31*5113495bSYour Name
32*5113495bSYour Name /* Helper functions */
33*5113495bSYour Name
34*5113495bSYour Name static int target_if_populate_report_static_gen2(
35*5113495bSYour Name struct spectralsim_report *report,
36*5113495bSYour Name enum phy_ch_width width, bool is_80_80);
37*5113495bSYour Name static int target_if_populate_report_static_gen3(
38*5113495bSYour Name struct spectralsim_report *report,
39*5113495bSYour Name enum phy_ch_width width, bool is_80_80);
40*5113495bSYour Name static void target_if_depopulate_report(
41*5113495bSYour Name struct spectralsim_report *report);
42*5113495bSYour Name
43*5113495bSYour Name static int target_if_populate_reportset_static(
44*5113495bSYour Name struct spectralsim_context *simctx,
45*5113495bSYour Name struct spectralsim_reportset *reportset,
46*5113495bSYour Name enum phy_ch_width width, bool is_80_80);
47*5113495bSYour Name static void target_if_depopulate_reportset(
48*5113495bSYour Name struct spectralsim_reportset *
49*5113495bSYour Name reportset);
50*5113495bSYour Name
51*5113495bSYour Name static int target_if_populate_simdata(struct spectralsim_context *simctx);
52*5113495bSYour Name static void target_if_depopulate_simdata(struct spectralsim_context *simctx);
53*5113495bSYour Name static OS_TIMER_FUNC(target_if_spectral_sim_phyerrdelivery_handler);
54*5113495bSYour Name
55*5113495bSYour Name /*
56*5113495bSYour Name * Static configuration.
57*5113495bSYour Name * For now, we will be having a single configuration per BW, and a single
58*5113495bSYour Name * report per configuration (since we need the data only for ensuring correct
59*5113495bSYour Name * format handling).
60*5113495bSYour Name *
61*5113495bSYour Name * Extend this for more functionality if required in the future.
62*5113495bSYour Name */
63*5113495bSYour Name
64*5113495bSYour Name /**
65*5113495bSYour Name * target_if_populate_report_static_gen2() - Statically populate simulation
66*5113495bSYour Name * data for one report for generation 2 chipsets
67*5113495bSYour Name * @report: Pointer to spectral report data instance
68*5113495bSYour Name * @width : Channel bandwidth enumeration
69*5113495bSYour Name *
70*5113495bSYour Name * Statically populate simulation data for one report for generation 2 chipsets
71*5113495bSYour Name *
72*5113495bSYour Name * Return: 0 on success, negative error code on failure
73*5113495bSYour Name */
74*5113495bSYour Name static int
target_if_populate_report_static_gen2(struct spectralsim_report * report,enum phy_ch_width width)75*5113495bSYour Name target_if_populate_report_static_gen2(
76*5113495bSYour Name struct spectralsim_report *report,
77*5113495bSYour Name enum phy_ch_width width)
78*5113495bSYour Name {
79*5113495bSYour Name if (!report) {
80*5113495bSYour Name spectral_err("report pointer is null.");
81*5113495bSYour Name goto bad;
82*5113495bSYour Name }
83*5113495bSYour Name
84*5113495bSYour Name switch (width) {
85*5113495bSYour Name case CH_WIDTH_20MHZ:
86*5113495bSYour Name report->data = NULL;
87*5113495bSYour Name report->data = (uint8_t *)
88*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_20_gen2));
89*5113495bSYour Name
90*5113495bSYour Name if (!report->data)
91*5113495bSYour Name goto bad;
92*5113495bSYour Name
93*5113495bSYour Name report->datasize = sizeof(reportdata_20_gen2);
94*5113495bSYour Name qdf_mem_copy(report->data,
95*5113495bSYour Name reportdata_20_gen2, report->datasize);
96*5113495bSYour Name
97*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
98*5113495bSYour Name &rfqual_info_20, sizeof(report->rfqual_info));
99*5113495bSYour Name
100*5113495bSYour Name qdf_mem_copy(&report->chan_info,
101*5113495bSYour Name &chan_info_20, sizeof(report->chan_info));
102*5113495bSYour Name
103*5113495bSYour Name break;
104*5113495bSYour Name case CH_WIDTH_40MHZ:
105*5113495bSYour Name report->data = NULL;
106*5113495bSYour Name report->data = (uint8_t *)
107*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_40_gen2));
108*5113495bSYour Name
109*5113495bSYour Name if (!report->data)
110*5113495bSYour Name goto bad;
111*5113495bSYour Name
112*5113495bSYour Name report->datasize = sizeof(reportdata_40_gen2);
113*5113495bSYour Name qdf_mem_copy(report->data,
114*5113495bSYour Name reportdata_40_gen2, report->datasize);
115*5113495bSYour Name
116*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
117*5113495bSYour Name &rfqual_info_40, sizeof(report->rfqual_info));
118*5113495bSYour Name
119*5113495bSYour Name qdf_mem_copy(&report->chan_info,
120*5113495bSYour Name &chan_info_40, sizeof(report->chan_info));
121*5113495bSYour Name
122*5113495bSYour Name break;
123*5113495bSYour Name case CH_WIDTH_80MHZ:
124*5113495bSYour Name report->data = NULL;
125*5113495bSYour Name report->data = (uint8_t *)
126*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_80_gen2));
127*5113495bSYour Name
128*5113495bSYour Name if (!report->data)
129*5113495bSYour Name goto bad;
130*5113495bSYour Name
131*5113495bSYour Name report->datasize = sizeof(reportdata_80_gen2);
132*5113495bSYour Name qdf_mem_copy(report->data,
133*5113495bSYour Name reportdata_80_gen2, report->datasize);
134*5113495bSYour Name
135*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
136*5113495bSYour Name &rfqual_info_80, sizeof(report->rfqual_info));
137*5113495bSYour Name
138*5113495bSYour Name qdf_mem_copy(&report->chan_info,
139*5113495bSYour Name &chan_info_80, sizeof(report->chan_info));
140*5113495bSYour Name
141*5113495bSYour Name break;
142*5113495bSYour Name case CH_WIDTH_80P80MHZ:
143*5113495bSYour Name report->data = NULL;
144*5113495bSYour Name report->data = (uint8_t *)
145*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_80_80_gen2));
146*5113495bSYour Name
147*5113495bSYour Name if (!report->data)
148*5113495bSYour Name goto bad;
149*5113495bSYour Name
150*5113495bSYour Name report->datasize = sizeof(reportdata_80_80_gen2);
151*5113495bSYour Name qdf_mem_copy(report->data,
152*5113495bSYour Name reportdata_80_80_gen2, report->datasize);
153*5113495bSYour Name
154*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
155*5113495bSYour Name &rfqual_info_80_80,
156*5113495bSYour Name sizeof(report->rfqual_info));
157*5113495bSYour Name
158*5113495bSYour Name qdf_mem_copy(&report->chan_info,
159*5113495bSYour Name &chan_info_80_80,
160*5113495bSYour Name sizeof(report->chan_info));
161*5113495bSYour Name break;
162*5113495bSYour Name
163*5113495bSYour Name case CH_WIDTH_160MHZ:
164*5113495bSYour Name report->data = NULL;
165*5113495bSYour Name report->data = (uint8_t *)
166*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_160_gen2));
167*5113495bSYour Name
168*5113495bSYour Name if (!report->data)
169*5113495bSYour Name goto bad;
170*5113495bSYour Name
171*5113495bSYour Name report->datasize = sizeof(reportdata_160_gen2);
172*5113495bSYour Name qdf_mem_copy(report->data,
173*5113495bSYour Name reportdata_160_gen2, report->datasize);
174*5113495bSYour Name
175*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
176*5113495bSYour Name &rfqual_info_160,
177*5113495bSYour Name sizeof(report->rfqual_info));
178*5113495bSYour Name
179*5113495bSYour Name qdf_mem_copy(&report->chan_info,
180*5113495bSYour Name &chan_info_160, sizeof(report->chan_info));
181*5113495bSYour Name break;
182*5113495bSYour Name
183*5113495bSYour Name default:
184*5113495bSYour Name spectral_err("Unhandled width enum: %d. Please correct.",
185*5113495bSYour Name width);
186*5113495bSYour Name goto bad;
187*5113495bSYour Name }
188*5113495bSYour Name
189*5113495bSYour Name return 0;
190*5113495bSYour Name
191*5113495bSYour Name bad:
192*5113495bSYour Name return -EPERM;
193*5113495bSYour Name }
194*5113495bSYour Name
195*5113495bSYour Name /**
196*5113495bSYour Name * target_if_populate_report_static_gen3() - Statically populate simulation
197*5113495bSYour Name * data for one report for generation 3 chipsets
198*5113495bSYour Name * @report: Pointer to spectral report data instance
199*5113495bSYour Name * @width : Channel bandwidth enumeration
200*5113495bSYour Name *
201*5113495bSYour Name * Statically populate simulation data for one report for generation 3 chipsets
202*5113495bSYour Name *
203*5113495bSYour Name * Return: 0 on success, negative error code on failure
204*5113495bSYour Name */
205*5113495bSYour Name static int
target_if_populate_report_static_gen3(struct spectralsim_report * report,enum phy_ch_width width)206*5113495bSYour Name target_if_populate_report_static_gen3(
207*5113495bSYour Name struct spectralsim_report *report,
208*5113495bSYour Name enum phy_ch_width width)
209*5113495bSYour Name {
210*5113495bSYour Name if (!report) {
211*5113495bSYour Name spectral_err("report pointer is null");
212*5113495bSYour Name goto bad;
213*5113495bSYour Name }
214*5113495bSYour Name switch (width) {
215*5113495bSYour Name case CH_WIDTH_20MHZ:
216*5113495bSYour Name report->data = NULL;
217*5113495bSYour Name report->data = (uint8_t *)
218*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_20_gen3));
219*5113495bSYour Name
220*5113495bSYour Name if (!report->data)
221*5113495bSYour Name goto bad;
222*5113495bSYour Name
223*5113495bSYour Name report->datasize = sizeof(reportdata_20_gen3);
224*5113495bSYour Name qdf_mem_copy(report->data,
225*5113495bSYour Name reportdata_20_gen3, report->datasize);
226*5113495bSYour Name
227*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
228*5113495bSYour Name &rfqual_info_20, sizeof(report->rfqual_info));
229*5113495bSYour Name
230*5113495bSYour Name qdf_mem_copy(&report->chan_info,
231*5113495bSYour Name &chan_info_20, sizeof(report->chan_info));
232*5113495bSYour Name
233*5113495bSYour Name break;
234*5113495bSYour Name case CH_WIDTH_40MHZ:
235*5113495bSYour Name report->data = NULL;
236*5113495bSYour Name report->data = (uint8_t *)
237*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_40_gen3));
238*5113495bSYour Name
239*5113495bSYour Name if (!report->data)
240*5113495bSYour Name goto bad;
241*5113495bSYour Name
242*5113495bSYour Name report->datasize = sizeof(reportdata_40_gen3);
243*5113495bSYour Name qdf_mem_copy(report->data,
244*5113495bSYour Name reportdata_40_gen3, report->datasize);
245*5113495bSYour Name
246*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
247*5113495bSYour Name &rfqual_info_40, sizeof(report->rfqual_info));
248*5113495bSYour Name
249*5113495bSYour Name qdf_mem_copy(&report->chan_info,
250*5113495bSYour Name &chan_info_40, sizeof(report->chan_info));
251*5113495bSYour Name
252*5113495bSYour Name break;
253*5113495bSYour Name case CH_WIDTH_80MHZ:
254*5113495bSYour Name report->data = NULL;
255*5113495bSYour Name report->data = (uint8_t *)
256*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_80_gen3));
257*5113495bSYour Name
258*5113495bSYour Name if (!report->data)
259*5113495bSYour Name goto bad;
260*5113495bSYour Name
261*5113495bSYour Name report->datasize = sizeof(reportdata_80_gen3);
262*5113495bSYour Name qdf_mem_copy(report->data,
263*5113495bSYour Name reportdata_80_gen3, report->datasize);
264*5113495bSYour Name
265*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
266*5113495bSYour Name &rfqual_info_80, sizeof(report->rfqual_info));
267*5113495bSYour Name
268*5113495bSYour Name qdf_mem_copy(&report->chan_info,
269*5113495bSYour Name &chan_info_80, sizeof(report->chan_info));
270*5113495bSYour Name
271*5113495bSYour Name break;
272*5113495bSYour Name
273*5113495bSYour Name case CH_WIDTH_80P80MHZ:
274*5113495bSYour Name report->data = NULL;
275*5113495bSYour Name report->data = (uint8_t *)
276*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_80_80_gen3));
277*5113495bSYour Name
278*5113495bSYour Name if (!report->data)
279*5113495bSYour Name goto bad;
280*5113495bSYour Name
281*5113495bSYour Name report->datasize = sizeof(reportdata_80_80_gen3);
282*5113495bSYour Name qdf_mem_copy(report->data,
283*5113495bSYour Name reportdata_80_80_gen3, report->datasize);
284*5113495bSYour Name
285*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
286*5113495bSYour Name &rfqual_info_80_80,
287*5113495bSYour Name sizeof(report->rfqual_info));
288*5113495bSYour Name
289*5113495bSYour Name qdf_mem_copy(&report->chan_info,
290*5113495bSYour Name &chan_info_80_80,
291*5113495bSYour Name sizeof(report->chan_info));
292*5113495bSYour Name break;
293*5113495bSYour Name
294*5113495bSYour Name case CH_WIDTH_160MHZ:
295*5113495bSYour Name report->data = NULL;
296*5113495bSYour Name report->data = (uint8_t *)
297*5113495bSYour Name qdf_mem_malloc(sizeof(reportdata_160_gen3));
298*5113495bSYour Name
299*5113495bSYour Name if (!report->data)
300*5113495bSYour Name goto bad;
301*5113495bSYour Name
302*5113495bSYour Name report->datasize = sizeof(reportdata_160_gen3);
303*5113495bSYour Name qdf_mem_copy(report->data,
304*5113495bSYour Name reportdata_160_gen3, report->datasize);
305*5113495bSYour Name
306*5113495bSYour Name qdf_mem_copy(&report->rfqual_info,
307*5113495bSYour Name &rfqual_info_160,
308*5113495bSYour Name sizeof(report->rfqual_info));
309*5113495bSYour Name
310*5113495bSYour Name qdf_mem_copy(&report->chan_info,
311*5113495bSYour Name &chan_info_160, sizeof(report->chan_info));
312*5113495bSYour Name break;
313*5113495bSYour Name
314*5113495bSYour Name default:
315*5113495bSYour Name spectral_err("Unhandled width enum: %d. Please correct.",
316*5113495bSYour Name width);
317*5113495bSYour Name goto bad;
318*5113495bSYour Name }
319*5113495bSYour Name
320*5113495bSYour Name return 0;
321*5113495bSYour Name
322*5113495bSYour Name bad:
323*5113495bSYour Name return -EPERM;
324*5113495bSYour Name }
325*5113495bSYour Name
326*5113495bSYour Name /**
327*5113495bSYour Name * target_if_depopulate_report() - Free the given instances of
328*5113495bSYour Name * struct spectralsim_report
329*5113495bSYour Name * @report: instance of struct spectralsim_report
330*5113495bSYour Name *
331*5113495bSYour Name * Free the given instances of struct spectralsim_report
332*5113495bSYour Name *
333*5113495bSYour Name * Return: None
334*5113495bSYour Name */
335*5113495bSYour Name static void
target_if_depopulate_report(struct spectralsim_report * report)336*5113495bSYour Name target_if_depopulate_report(
337*5113495bSYour Name struct spectralsim_report *report)
338*5113495bSYour Name {
339*5113495bSYour Name if (!report)
340*5113495bSYour Name return;
341*5113495bSYour Name
342*5113495bSYour Name if (report->data) {
343*5113495bSYour Name qdf_mem_free(report->data);
344*5113495bSYour Name report->data = NULL;
345*5113495bSYour Name report->datasize = 0;
346*5113495bSYour Name }
347*5113495bSYour Name }
348*5113495bSYour Name
349*5113495bSYour Name /**
350*5113495bSYour Name * target_if_populate_reportset_static() - Statically populate simulation data
351*5113495bSYour Name * for a given configuration
352*5113495bSYour Name * @simctx: Pointer to struct spectralsim_context
353*5113495bSYour Name * @reportset: Set of spectral report data instances
354*5113495bSYour Name * @width : Channel bandwidth enumeration
355*5113495bSYour Name *
356*5113495bSYour Name * Statically populate simulation data for a given configuration
357*5113495bSYour Name *
358*5113495bSYour Name * Return: 0 on success, negative error code on failure
359*5113495bSYour Name */
360*5113495bSYour Name static int
target_if_populate_reportset_static(struct spectralsim_context * simctx,struct spectralsim_reportset * reportset,enum phy_ch_width width)361*5113495bSYour Name target_if_populate_reportset_static(
362*5113495bSYour Name struct spectralsim_context *simctx,
363*5113495bSYour Name struct spectralsim_reportset *reportset,
364*5113495bSYour Name enum phy_ch_width width)
365*5113495bSYour Name {
366*5113495bSYour Name int ret = 0;
367*5113495bSYour Name struct spectralsim_report *report = NULL;
368*5113495bSYour Name
369*5113495bSYour Name if (!reportset) {
370*5113495bSYour Name spectral_err("reportset pointer is null.");
371*5113495bSYour Name goto bad;
372*5113495bSYour Name }
373*5113495bSYour Name
374*5113495bSYour Name reportset->headreport = NULL;
375*5113495bSYour Name reportset->curr_report = NULL;
376*5113495bSYour Name
377*5113495bSYour Name /* For now, we populate only one report */
378*5113495bSYour Name report = (struct spectralsim_report *)
379*5113495bSYour Name qdf_mem_malloc(sizeof(struct spectralsim_report));
380*5113495bSYour Name
381*5113495bSYour Name if (!report)
382*5113495bSYour Name goto bad;
383*5113495bSYour Name
384*5113495bSYour Name qdf_mem_zero(report, sizeof(*report));
385*5113495bSYour Name
386*5113495bSYour Name switch (width) {
387*5113495bSYour Name case CH_WIDTH_20MHZ:
388*5113495bSYour Name qdf_mem_copy(&reportset->config,
389*5113495bSYour Name &config_20_1, sizeof(reportset->config));
390*5113495bSYour Name
391*5113495bSYour Name ret = simctx->populate_report_static(report, CH_WIDTH_20MHZ);
392*5113495bSYour Name if (ret != 0)
393*5113495bSYour Name goto bad;
394*5113495bSYour Name
395*5113495bSYour Name report->next = NULL;
396*5113495bSYour Name reportset->headreport = report;
397*5113495bSYour Name break;
398*5113495bSYour Name case CH_WIDTH_40MHZ:
399*5113495bSYour Name qdf_mem_copy(&reportset->config,
400*5113495bSYour Name &config_40_1, sizeof(reportset->config));
401*5113495bSYour Name
402*5113495bSYour Name ret = simctx->populate_report_static(report, CH_WIDTH_40MHZ);
403*5113495bSYour Name if (ret != 0)
404*5113495bSYour Name goto bad;
405*5113495bSYour Name
406*5113495bSYour Name report->next = NULL;
407*5113495bSYour Name reportset->headreport = report;
408*5113495bSYour Name break;
409*5113495bSYour Name case CH_WIDTH_80MHZ:
410*5113495bSYour Name qdf_mem_copy(&reportset->config,
411*5113495bSYour Name &config_80_1, sizeof(reportset->config));
412*5113495bSYour Name
413*5113495bSYour Name ret = simctx->populate_report_static(report, CH_WIDTH_80MHZ);
414*5113495bSYour Name if (ret != 0)
415*5113495bSYour Name goto bad;
416*5113495bSYour Name
417*5113495bSYour Name report->next = NULL;
418*5113495bSYour Name reportset->headreport = report;
419*5113495bSYour Name break;
420*5113495bSYour Name
421*5113495bSYour Name case CH_WIDTH_80P80MHZ:
422*5113495bSYour Name qdf_mem_copy(&reportset->config,
423*5113495bSYour Name &config_80_80_1,
424*5113495bSYour Name sizeof(reportset->config));
425*5113495bSYour Name
426*5113495bSYour Name ret = simctx->populate_report_static(report,
427*5113495bSYour Name CH_WIDTH_80P80MHZ);
428*5113495bSYour Name if (ret != 0)
429*5113495bSYour Name goto bad;
430*5113495bSYour Name
431*5113495bSYour Name report->next = NULL;
432*5113495bSYour Name reportset->headreport = report;
433*5113495bSYour Name break;
434*5113495bSYour Name
435*5113495bSYour Name case CH_WIDTH_160MHZ:
436*5113495bSYour Name qdf_mem_copy(&reportset->config,
437*5113495bSYour Name &config_160_1, sizeof(reportset->config));
438*5113495bSYour Name
439*5113495bSYour Name ret = simctx->populate_report_static(report,
440*5113495bSYour Name CH_WIDTH_160MHZ);
441*5113495bSYour Name if (ret != 0)
442*5113495bSYour Name goto bad;
443*5113495bSYour Name
444*5113495bSYour Name report->next = NULL;
445*5113495bSYour Name reportset->headreport = report;
446*5113495bSYour Name break;
447*5113495bSYour Name
448*5113495bSYour Name default:
449*5113495bSYour Name spectral_err("Unhandled width enum: %d. Please correct.",
450*5113495bSYour Name width);
451*5113495bSYour Name goto bad;
452*5113495bSYour Name };
453*5113495bSYour Name
454*5113495bSYour Name reportset->curr_report = reportset->headreport;
455*5113495bSYour Name
456*5113495bSYour Name return 0;
457*5113495bSYour Name
458*5113495bSYour Name bad:
459*5113495bSYour Name target_if_depopulate_reportset(reportset);
460*5113495bSYour Name return -EPERM;
461*5113495bSYour Name }
462*5113495bSYour Name
463*5113495bSYour Name /**
464*5113495bSYour Name * target_if_depopulate_reportset() - Free all the instances of
465*5113495bSYour Name * struct spectralsim_reportset
466*5113495bSYour Name * @reportset: head pointer to struct spectralsim_reportset linked list
467*5113495bSYour Name *
468*5113495bSYour Name * Free all the instances of struct spectralsim_reportset
469*5113495bSYour Name *
470*5113495bSYour Name * Return: None
471*5113495bSYour Name */
472*5113495bSYour Name static void
target_if_depopulate_reportset(struct spectralsim_reportset * reportset)473*5113495bSYour Name target_if_depopulate_reportset(
474*5113495bSYour Name struct spectralsim_reportset *reportset)
475*5113495bSYour Name {
476*5113495bSYour Name struct spectralsim_report *curr_report = NULL;
477*5113495bSYour Name struct spectralsim_report *next_report = NULL;
478*5113495bSYour Name
479*5113495bSYour Name if (!reportset)
480*5113495bSYour Name return;
481*5113495bSYour Name
482*5113495bSYour Name curr_report = reportset->headreport;
483*5113495bSYour Name
484*5113495bSYour Name while (curr_report) {
485*5113495bSYour Name next_report = curr_report->next;
486*5113495bSYour Name target_if_depopulate_report(curr_report);
487*5113495bSYour Name qdf_mem_free(curr_report);
488*5113495bSYour Name curr_report = next_report;
489*5113495bSYour Name }
490*5113495bSYour Name }
491*5113495bSYour Name
492*5113495bSYour Name /**
493*5113495bSYour Name * target_if_populate_simdata() - Populate simulation data
494*5113495bSYour Name * @simctx: Pointer to struct spectralsim_context
495*5113495bSYour Name *
496*5113495bSYour Name * Populate simulation data
497*5113495bSYour Name *
498*5113495bSYour Name * Return: 0 on success, negative error code on failure
499*5113495bSYour Name */
500*5113495bSYour Name static int
target_if_populate_simdata(struct spectralsim_context * simctx)501*5113495bSYour Name target_if_populate_simdata(
502*5113495bSYour Name struct spectralsim_context *simctx)
503*5113495bSYour Name {
504*5113495bSYour Name /*
505*5113495bSYour Name * For now, we use static population. Switch to loading from a file if
506*5113495bSYour Name * needed in the future.
507*5113495bSYour Name */
508*5113495bSYour Name
509*5113495bSYour Name simctx->bw20_headreportset = NULL;
510*5113495bSYour Name SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
511*5113495bSYour Name simctx->bw20_headreportset,
512*5113495bSYour Name CH_WIDTH_20MHZ);
513*5113495bSYour Name
514*5113495bSYour Name simctx->bw40_headreportset = NULL;
515*5113495bSYour Name SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
516*5113495bSYour Name simctx->bw40_headreportset,
517*5113495bSYour Name CH_WIDTH_40MHZ);
518*5113495bSYour Name
519*5113495bSYour Name simctx->bw80_headreportset = NULL;
520*5113495bSYour Name SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
521*5113495bSYour Name simctx->bw80_headreportset,
522*5113495bSYour Name CH_WIDTH_80MHZ);
523*5113495bSYour Name
524*5113495bSYour Name simctx->bw160_headreportset = NULL;
525*5113495bSYour Name SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
526*5113495bSYour Name simctx->bw160_headreportset,
527*5113495bSYour Name CH_WIDTH_160MHZ);
528*5113495bSYour Name
529*5113495bSYour Name simctx->bw80_80_headreportset = NULL;
530*5113495bSYour Name SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
531*5113495bSYour Name simctx->bw80_80_headreportset,
532*5113495bSYour Name CH_WIDTH_80P80MHZ);
533*5113495bSYour Name
534*5113495bSYour Name simctx->curr_reportset = NULL;
535*5113495bSYour Name
536*5113495bSYour Name simctx->is_enabled = false;
537*5113495bSYour Name simctx->is_active = false;
538*5113495bSYour Name
539*5113495bSYour Name simctx->ssim_starting_tsf64 = 0;
540*5113495bSYour Name simctx->ssim_count = 0;
541*5113495bSYour Name simctx->ssim_period_ms = 0;
542*5113495bSYour Name
543*5113495bSYour Name return 0;
544*5113495bSYour Name }
545*5113495bSYour Name
546*5113495bSYour Name /**
547*5113495bSYour Name * target_if_depopulate_simdata() - De-populate simulation data
548*5113495bSYour Name * @simctx: Pointer to struct spectralsim_context
549*5113495bSYour Name *
550*5113495bSYour Name * De-populate simulation data
551*5113495bSYour Name *
552*5113495bSYour Name * Return: none
553*5113495bSYour Name */
554*5113495bSYour Name static void
target_if_depopulate_simdata(struct spectralsim_context * simctx)555*5113495bSYour Name target_if_depopulate_simdata(
556*5113495bSYour Name struct spectralsim_context *simctx)
557*5113495bSYour Name {
558*5113495bSYour Name if (!simctx)
559*5113495bSYour Name return;
560*5113495bSYour Name
561*5113495bSYour Name SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw20_headreportset);
562*5113495bSYour Name SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw40_headreportset);
563*5113495bSYour Name SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw80_headreportset);
564*5113495bSYour Name SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw160_headreportset);
565*5113495bSYour Name SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw80_80_headreportset);
566*5113495bSYour Name }
567*5113495bSYour Name
568*5113495bSYour Name /*
569*5113495bSYour Name * target_if_spectral_sim_phyerrdelivery_handler() - Phyerr delivery handler
570*5113495bSYour Name *
571*5113495bSYour Name * Return: none
572*5113495bSYour Name *
573*5113495bSYour Name * NB: kernel-doc script doesn't parse OS_TIMER_FUNC
574*5113495bSYour Name */
575*5113495bSYour Name static
OS_TIMER_FUNC(target_if_spectral_sim_phyerrdelivery_handler)576*5113495bSYour Name OS_TIMER_FUNC(target_if_spectral_sim_phyerrdelivery_handler)
577*5113495bSYour Name {
578*5113495bSYour Name struct target_if_spectral *spectral = NULL;
579*5113495bSYour Name struct spectralsim_context *simctx = NULL;
580*5113495bSYour Name struct spectralsim_reportset *curr_reportset = NULL;
581*5113495bSYour Name struct spectralsim_report *curr_report = NULL;
582*5113495bSYour Name struct target_if_spectral_acs_stats acs_stats;
583*5113495bSYour Name uint64_t curr_tsf64 = 0;
584*5113495bSYour Name struct target_if_spectral_ops *p_sops;
585*5113495bSYour Name
586*5113495bSYour Name OS_GET_TIMER_ARG(spectral, struct target_if_spectral *);
587*5113495bSYour Name if (!spectral) {
588*5113495bSYour Name spectral_err("spectral pointer is null.");
589*5113495bSYour Name return;
590*5113495bSYour Name }
591*5113495bSYour Name
592*5113495bSYour Name p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral);
593*5113495bSYour Name if (!p_sops) {
594*5113495bSYour Name spectral_err("p_sops pointer is null.");
595*5113495bSYour Name return;
596*5113495bSYour Name }
597*5113495bSYour Name
598*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
599*5113495bSYour Name if (!simctx) {
600*5113495bSYour Name spectral_err("simctx pointer is null.");
601*5113495bSYour Name return;
602*5113495bSYour Name }
603*5113495bSYour Name
604*5113495bSYour Name if (!simctx->is_active)
605*5113495bSYour Name return;
606*5113495bSYour Name
607*5113495bSYour Name curr_reportset = simctx->curr_reportset;
608*5113495bSYour Name if (!curr_reportset) {
609*5113495bSYour Name spectral_err("curr_reportset pointer is null.");
610*5113495bSYour Name return;
611*5113495bSYour Name }
612*5113495bSYour Name
613*5113495bSYour Name curr_report = curr_reportset->curr_report;
614*5113495bSYour Name if (!curr_report) {
615*5113495bSYour Name spectral_err("curr_report pointer is null.");
616*5113495bSYour Name return;
617*5113495bSYour Name }
618*5113495bSYour Name
619*5113495bSYour Name if (!curr_reportset->headreport) {
620*5113495bSYour Name spectral_err("curr_reportset->headreport pointer is null.");
621*5113495bSYour Name return;
622*5113495bSYour Name }
623*5113495bSYour Name
624*5113495bSYour Name /*
625*5113495bSYour Name * We use a simulation TSF since in offload architectures we can't
626*5113495bSYour Name * expect to
627*5113495bSYour Name * get an accurate current TSF from HW.
628*5113495bSYour Name * In case of TSF wrap over, we'll use it as-is for now since the
629*5113495bSYour Name * simulation
630*5113495bSYour Name * is intended only for format verification.
631*5113495bSYour Name */
632*5113495bSYour Name curr_tsf64 = simctx->ssim_starting_tsf64 +
633*5113495bSYour Name ((simctx->ssim_period_ms * simctx->ssim_count) * 1000);
634*5113495bSYour Name
635*5113495bSYour Name p_sops->spectral_process_phyerr(spectral,
636*5113495bSYour Name curr_report->data,
637*5113495bSYour Name curr_report->datasize,
638*5113495bSYour Name &curr_report->rfqual_info,
639*5113495bSYour Name &curr_report->chan_info,
640*5113495bSYour Name curr_tsf64, &acs_stats);
641*5113495bSYour Name
642*5113495bSYour Name simctx->ssim_count++;
643*5113495bSYour Name
644*5113495bSYour Name if (curr_report->next)
645*5113495bSYour Name curr_reportset->curr_report = curr_report->next;
646*5113495bSYour Name else
647*5113495bSYour Name curr_reportset->curr_report = curr_reportset->headreport;
648*5113495bSYour Name
649*5113495bSYour Name if (curr_reportset->config.ss_count != 0 &&
650*5113495bSYour Name simctx->ssim_count == curr_reportset->config.ss_count) {
651*5113495bSYour Name target_if_spectral_sops_sim_stop_scan(spectral);
652*5113495bSYour Name } else {
653*5113495bSYour Name qdf_timer_start(&simctx->ssim_pherrdelivery_timer,
654*5113495bSYour Name simctx->ssim_period_ms);
655*5113495bSYour Name }
656*5113495bSYour Name }
657*5113495bSYour Name
658*5113495bSYour Name /* Module services */
659*5113495bSYour Name
660*5113495bSYour Name int
target_if_spectral_sim_attach(struct target_if_spectral * spectral)661*5113495bSYour Name target_if_spectral_sim_attach(struct target_if_spectral *spectral)
662*5113495bSYour Name {
663*5113495bSYour Name struct spectralsim_context *simctx = NULL;
664*5113495bSYour Name
665*5113495bSYour Name if (!spectral) {
666*5113495bSYour Name spectral_err("Spectral simulation: spectral pointer is null.")
667*5113495bSYour Name return -EPERM;
668*5113495bSYour Name }
669*5113495bSYour Name
670*5113495bSYour Name simctx = (struct spectralsim_context *)
671*5113495bSYour Name qdf_mem_malloc(sizeof(struct spectralsim_context));
672*5113495bSYour Name
673*5113495bSYour Name if (!simctx)
674*5113495bSYour Name return -EPERM;
675*5113495bSYour Name
676*5113495bSYour Name qdf_mem_zero(simctx, sizeof(*simctx));
677*5113495bSYour Name
678*5113495bSYour Name spectral->simctx = simctx;
679*5113495bSYour Name
680*5113495bSYour Name if (spectral->spectral_gen == SPECTRAL_GEN2)
681*5113495bSYour Name simctx->populate_report_static =
682*5113495bSYour Name target_if_populate_report_static_gen2;
683*5113495bSYour Name else if (spectral->spectral_gen == SPECTRAL_GEN3)
684*5113495bSYour Name simctx->populate_report_static =
685*5113495bSYour Name target_if_populate_report_static_gen3;
686*5113495bSYour Name
687*5113495bSYour Name if (target_if_populate_simdata(simctx) != 0) {
688*5113495bSYour Name qdf_mem_free(simctx);
689*5113495bSYour Name spectral->simctx = NULL;
690*5113495bSYour Name spectral_err("Spectral simulation attach failed");
691*5113495bSYour Name return -EPERM;
692*5113495bSYour Name }
693*5113495bSYour Name
694*5113495bSYour Name qdf_timer_init(NULL,
695*5113495bSYour Name &simctx->ssim_pherrdelivery_timer,
696*5113495bSYour Name target_if_spectral_sim_phyerrdelivery_handler,
697*5113495bSYour Name (void *)(spectral), QDF_TIMER_TYPE_WAKE_APPS);
698*5113495bSYour Name
699*5113495bSYour Name spectral_info("Spectral simulation attached");
700*5113495bSYour Name
701*5113495bSYour Name return 0;
702*5113495bSYour Name }
703*5113495bSYour Name
704*5113495bSYour Name void
target_if_spectral_sim_detach(struct target_if_spectral * spectral)705*5113495bSYour Name target_if_spectral_sim_detach(struct target_if_spectral *spectral)
706*5113495bSYour Name {
707*5113495bSYour Name struct spectralsim_context *simctx = NULL;
708*5113495bSYour Name
709*5113495bSYour Name if (!spectral) {
710*5113495bSYour Name spectral_err("spectral pointer is null.");
711*5113495bSYour Name return;
712*5113495bSYour Name }
713*5113495bSYour Name
714*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
715*5113495bSYour Name if (!simctx) {
716*5113495bSYour Name spectral_err("simctx pointer is null.");
717*5113495bSYour Name return;
718*5113495bSYour Name }
719*5113495bSYour Name
720*5113495bSYour Name qdf_timer_free(&simctx->ssim_pherrdelivery_timer);
721*5113495bSYour Name
722*5113495bSYour Name target_if_depopulate_simdata(simctx);
723*5113495bSYour Name qdf_mem_free(simctx);
724*5113495bSYour Name spectral->simctx = NULL;
725*5113495bSYour Name
726*5113495bSYour Name spectral_info("Spectral simulation detached");
727*5113495bSYour Name }
728*5113495bSYour Name
729*5113495bSYour Name uint32_t
target_if_spectral_sops_sim_is_active(void * arg)730*5113495bSYour Name target_if_spectral_sops_sim_is_active(void *arg)
731*5113495bSYour Name {
732*5113495bSYour Name struct target_if_spectral *spectral = NULL;
733*5113495bSYour Name struct spectralsim_context *simctx = NULL;
734*5113495bSYour Name
735*5113495bSYour Name spectral = (struct target_if_spectral *)arg;
736*5113495bSYour Name if (!spectral) {
737*5113495bSYour Name spectral_err("Spectral simulation: spectral pointer is null");
738*5113495bSYour Name return 0;
739*5113495bSYour Name }
740*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
741*5113495bSYour Name if (!simctx) {
742*5113495bSYour Name spectral_err("Spectral simulation: simctx pointer is null");
743*5113495bSYour Name return 0;
744*5113495bSYour Name }
745*5113495bSYour Name
746*5113495bSYour Name return simctx->is_active;
747*5113495bSYour Name }
748*5113495bSYour Name qdf_export_symbol(target_if_spectral_sops_sim_is_active);
749*5113495bSYour Name
750*5113495bSYour Name uint32_t
target_if_spectral_sops_sim_is_enabled(void * arg)751*5113495bSYour Name target_if_spectral_sops_sim_is_enabled(void *arg)
752*5113495bSYour Name {
753*5113495bSYour Name struct target_if_spectral *spectral = NULL;
754*5113495bSYour Name struct spectralsim_context *simctx = NULL;
755*5113495bSYour Name
756*5113495bSYour Name spectral = (struct target_if_spectral *)arg;
757*5113495bSYour Name if (!spectral) {
758*5113495bSYour Name spectral_err("Spectral simulation: spectral pointer is null");
759*5113495bSYour Name return 0;
760*5113495bSYour Name }
761*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
762*5113495bSYour Name if (!simctx) {
763*5113495bSYour Name spectral_err("Spectral simulation: simctx pointer is null");
764*5113495bSYour Name return 0;
765*5113495bSYour Name }
766*5113495bSYour Name
767*5113495bSYour Name return simctx->is_enabled;
768*5113495bSYour Name }
769*5113495bSYour Name qdf_export_symbol(target_if_spectral_sops_sim_is_enabled);
770*5113495bSYour Name
771*5113495bSYour Name uint32_t
target_if_spectral_sops_sim_start_scan(void * arg)772*5113495bSYour Name target_if_spectral_sops_sim_start_scan(void *arg)
773*5113495bSYour Name {
774*5113495bSYour Name struct target_if_spectral *spectral = NULL;
775*5113495bSYour Name struct spectralsim_context *simctx = NULL;
776*5113495bSYour Name
777*5113495bSYour Name spectral = (struct target_if_spectral *)arg;
778*5113495bSYour Name if (!spectral) {
779*5113495bSYour Name spectral_err("Spectral simulation: spectral pointer is null");
780*5113495bSYour Name return 0;
781*5113495bSYour Name }
782*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
783*5113495bSYour Name if (!simctx) {
784*5113495bSYour Name spectral_err("Spectral simulation: simctx pointer is null");
785*5113495bSYour Name return 0;
786*5113495bSYour Name }
787*5113495bSYour Name
788*5113495bSYour Name if (!simctx->curr_reportset) {
789*5113495bSYour Name spectral_err("Spectral simulation: No current report set configured - unable to start simulated Spectral scan");
790*5113495bSYour Name return 0;
791*5113495bSYour Name }
792*5113495bSYour Name
793*5113495bSYour Name if (!simctx->curr_reportset->curr_report) {
794*5113495bSYour Name spectral_err("Spectral simulation: No report data instances populated - unable to start simulated Spectral scan");
795*5113495bSYour Name return 0;
796*5113495bSYour Name }
797*5113495bSYour Name
798*5113495bSYour Name if (!simctx->is_enabled)
799*5113495bSYour Name simctx->is_enabled = true;
800*5113495bSYour Name
801*5113495bSYour Name simctx->is_active = true;
802*5113495bSYour Name
803*5113495bSYour Name /* Hardcoding current time as zero since it is simulation */
804*5113495bSYour Name simctx->ssim_starting_tsf64 = 0;
805*5113495bSYour Name simctx->ssim_count = 0;
806*5113495bSYour Name
807*5113495bSYour Name /*
808*5113495bSYour Name * TODO: Support high resolution timer in microseconds if required, so
809*5113495bSYour Name * that
810*5113495bSYour Name * we can support default periods such as ~200 us. For now, we use 1
811*5113495bSYour Name * millisecond since the current use case for the simulation is to
812*5113495bSYour Name * validate
813*5113495bSYour Name * formats rather than have a time dependent classification.
814*5113495bSYour Name */
815*5113495bSYour Name simctx->ssim_period_ms = 1;
816*5113495bSYour Name
817*5113495bSYour Name qdf_timer_start(&simctx->ssim_pherrdelivery_timer,
818*5113495bSYour Name simctx->ssim_period_ms);
819*5113495bSYour Name
820*5113495bSYour Name return 1;
821*5113495bSYour Name }
822*5113495bSYour Name qdf_export_symbol(target_if_spectral_sops_sim_start_scan);
823*5113495bSYour Name
824*5113495bSYour Name uint32_t
target_if_spectral_sops_sim_stop_scan(void * arg)825*5113495bSYour Name target_if_spectral_sops_sim_stop_scan(void *arg)
826*5113495bSYour Name {
827*5113495bSYour Name struct target_if_spectral *spectral = NULL;
828*5113495bSYour Name struct spectralsim_context *simctx = NULL;
829*5113495bSYour Name
830*5113495bSYour Name spectral = (struct target_if_spectral *)arg;
831*5113495bSYour Name if (!spectral) {
832*5113495bSYour Name spectral_err("Spectral simulation: spectral pointer is null");
833*5113495bSYour Name return 0;
834*5113495bSYour Name }
835*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
836*5113495bSYour Name if (!simctx) {
837*5113495bSYour Name spectral_err("Spectral simulation: simctx pointer is null");
838*5113495bSYour Name return 0;
839*5113495bSYour Name }
840*5113495bSYour Name
841*5113495bSYour Name qdf_timer_stop(&simctx->ssim_pherrdelivery_timer);
842*5113495bSYour Name
843*5113495bSYour Name simctx->is_active = false;
844*5113495bSYour Name simctx->is_enabled = false;
845*5113495bSYour Name
846*5113495bSYour Name simctx->ssim_starting_tsf64 = 0;
847*5113495bSYour Name simctx->ssim_count = 0;
848*5113495bSYour Name simctx->ssim_period_ms = 0;
849*5113495bSYour Name
850*5113495bSYour Name return 1;
851*5113495bSYour Name }
852*5113495bSYour Name qdf_export_symbol(target_if_spectral_sops_sim_stop_scan);
853*5113495bSYour Name
854*5113495bSYour Name #ifdef SPECTRAL_SIM_DUMP_PARAM_DATA
855*5113495bSYour Name static void
target_if_log_sim_spectral_params(struct spectral_config * params)856*5113495bSYour Name target_if_log_sim_spectral_params(struct spectral_config *params)
857*5113495bSYour Name {
858*5113495bSYour Name int i = 0;
859*5113495bSYour Name
860*5113495bSYour Name spectral_debug("\n");
861*5113495bSYour Name
862*5113495bSYour Name spectral_debug("Spectral simulation: Param data dump:\nss_fft_period=%hu\nss_period=%hu\nss_count=%hu\nss_short_report=%hu\nradar_bin_thresh_sel=%hhu\nss_spectral_pri=%hu\nss_fft_size=%hu\nss_gc_ena=%hu\nss_restart_ena=%hu\nss_noise_floor_ref=%hu\nss_init_delay=%hu\nss_nb_tone_thr=%hu\nss_str_bin_thr=%hu\nss_wb_rpt_mode=%hu\nss_rssi_rpt_mode=%hu\nss_rssi_thr=%hu\nss_pwr_format=%hu\nss_rpt_mode=%hu\nss_bin_scale=%hu\nss_dbm_adj=%hu\nss_chn_mask=%hu\nss_nf_temp_data=%d",
863*5113495bSYour Name params->ss_fft_period,
864*5113495bSYour Name params->ss_period,
865*5113495bSYour Name params->ss_count,
866*5113495bSYour Name params->ss_short_report,
867*5113495bSYour Name params->radar_bin_thresh_sel,
868*5113495bSYour Name params->ss_spectral_pri,
869*5113495bSYour Name params->ss_fft_size,
870*5113495bSYour Name params->ss_gc_ena,
871*5113495bSYour Name params->ss_restart_ena,
872*5113495bSYour Name params->ss_noise_floor_ref,
873*5113495bSYour Name params->ss_init_delay,
874*5113495bSYour Name params->ss_nb_tone_thr,
875*5113495bSYour Name params->ss_str_bin_thr,
876*5113495bSYour Name params->ss_wb_rpt_mode,
877*5113495bSYour Name params->ss_rssi_rpt_mode,
878*5113495bSYour Name params->ss_rssi_thr,
879*5113495bSYour Name params->ss_pwr_format,
880*5113495bSYour Name params->ss_rpt_mode,
881*5113495bSYour Name params->ss_bin_scale,
882*5113495bSYour Name params->ss_dbm_adj,
883*5113495bSYour Name params->ss_chn_mask, params->ss_nf_temp_data);
884*5113495bSYour Name
885*5113495bSYour Name for (i = 0; i < AH_MAX_CHAINS * 2; i++)
886*5113495bSYour Name spectral_debug("ss_nf_cal[%d]=%hhd", i, params->ss_nf_cal[i]);
887*5113495bSYour Name
888*5113495bSYour Name for (i = 0; i < AH_MAX_CHAINS * 2; i++)
889*5113495bSYour Name spectral_debug("ss_nf_pwr[%d]=%hhd", i, params->ss_nf_pwr[i]);
890*5113495bSYour Name
891*5113495bSYour Name spectral_info("\n");
892*5113495bSYour Name }
893*5113495bSYour Name #else
894*5113495bSYour Name
895*5113495bSYour Name static void
target_if_log_sim_spectral_params(struct spectral_config * params)896*5113495bSYour Name target_if_log_sim_spectral_params(struct spectral_config *params)
897*5113495bSYour Name {
898*5113495bSYour Name }
899*5113495bSYour Name #endif /* SPECTRAL_SIM_DUMP_PARAM_DATA */
900*5113495bSYour Name
901*5113495bSYour Name uint32_t
target_if_spectral_sops_sim_configure_params(void * arg,struct spectral_config * params,enum spectral_scan_mode smode)902*5113495bSYour Name target_if_spectral_sops_sim_configure_params(
903*5113495bSYour Name void *arg,
904*5113495bSYour Name struct spectral_config *params,
905*5113495bSYour Name enum spectral_scan_mode smode)
906*5113495bSYour Name {
907*5113495bSYour Name struct target_if_spectral *spectral = NULL;
908*5113495bSYour Name struct spectralsim_context *simctx = NULL;
909*5113495bSYour Name enum wlan_phymode phymode;
910*5113495bSYour Name uint8_t bw;
911*5113495bSYour Name struct spectralsim_reportset *des_headreportset = NULL;
912*5113495bSYour Name struct spectralsim_reportset *temp_reportset = NULL;
913*5113495bSYour Name struct wlan_objmgr_vdev *vdev = NULL;
914*5113495bSYour Name
915*5113495bSYour Name if (!params) {
916*5113495bSYour Name spectral_err("Spectral simulation: params pointer is null.")
917*5113495bSYour Name return 0;
918*5113495bSYour Name }
919*5113495bSYour Name target_if_log_sim_spectral_params(params);
920*5113495bSYour Name
921*5113495bSYour Name spectral = (struct target_if_spectral *)arg;
922*5113495bSYour Name if (!spectral) {
923*5113495bSYour Name spectral_err("Spectral simulation: spectral pointer is null");
924*5113495bSYour Name return 0;
925*5113495bSYour Name }
926*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
927*5113495bSYour Name if (!simctx) {
928*5113495bSYour Name spectral_err("Spectral simulation: simctx pointer is null");
929*5113495bSYour Name return 0;
930*5113495bSYour Name }
931*5113495bSYour Name
932*5113495bSYour Name vdev = target_if_spectral_get_vdev(spectral, smode);
933*5113495bSYour Name if (!vdev) {
934*5113495bSYour Name spectral_warn("Spectral simulation: No VAPs found - not proceeding with param config.");
935*5113495bSYour Name return 0;
936*5113495bSYour Name }
937*5113495bSYour Name
938*5113495bSYour Name bw = target_if_vdev_get_ch_width(vdev);
939*5113495bSYour Name
940*5113495bSYour Name switch (bw) {
941*5113495bSYour Name case CH_WIDTH_20MHZ:
942*5113495bSYour Name des_headreportset = simctx->bw20_headreportset;
943*5113495bSYour Name break;
944*5113495bSYour Name case CH_WIDTH_40MHZ:
945*5113495bSYour Name des_headreportset = simctx->bw40_headreportset;
946*5113495bSYour Name break;
947*5113495bSYour Name case CH_WIDTH_80MHZ:
948*5113495bSYour Name des_headreportset = simctx->bw80_headreportset;
949*5113495bSYour Name break;
950*5113495bSYour Name case CH_WIDTH_160MHZ:
951*5113495bSYour Name des_headreportset = simctx->bw160_headreportset;
952*5113495bSYour Name break;
953*5113495bSYour Name case CH_WIDTH_80P80MHZ:
954*5113495bSYour Name des_headreportset = simctx->bw80_80_headreportset;
955*5113495bSYour Name break;
956*5113495bSYour Name case CH_WIDTH_INVALID:
957*5113495bSYour Name default:
958*5113495bSYour Name spectral_err("Spectral simulation: Invalid width: %d configured - not proceeding with param config.",
959*5113495bSYour Name bw);
960*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
961*5113495bSYour Name return 0;
962*5113495bSYour Name }
963*5113495bSYour Name
964*5113495bSYour Name wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
965*5113495bSYour Name
966*5113495bSYour Name if (!des_headreportset) {
967*5113495bSYour Name spectral_warn("Spectral simulation: No simulation data present for configured bandwidth/PHY mode - unable to proceed with param config.");
968*5113495bSYour Name return 0;
969*5113495bSYour Name }
970*5113495bSYour Name
971*5113495bSYour Name simctx->curr_reportset = NULL;
972*5113495bSYour Name temp_reportset = des_headreportset;
973*5113495bSYour Name
974*5113495bSYour Name while (temp_reportset) {
975*5113495bSYour Name if (qdf_mem_cmp(&temp_reportset->config,
976*5113495bSYour Name params, sizeof(struct spectral_config)) == 0) {
977*5113495bSYour Name /* Found a matching config. We are done. */
978*5113495bSYour Name simctx->curr_reportset = temp_reportset;
979*5113495bSYour Name break;
980*5113495bSYour Name }
981*5113495bSYour Name
982*5113495bSYour Name temp_reportset = temp_reportset->next;
983*5113495bSYour Name }
984*5113495bSYour Name
985*5113495bSYour Name if (!simctx->curr_reportset) {
986*5113495bSYour Name spectral_warn("Spectral simulation: No simulation data present for desired Spectral configuration - unable to proceed with param config.");
987*5113495bSYour Name return 0;
988*5113495bSYour Name }
989*5113495bSYour Name
990*5113495bSYour Name if (!simctx->curr_reportset->curr_report) {
991*5113495bSYour Name spectral_warn("Spectral simulation: No report data instances populated for desired Spectral configuration - unable to proceed with param config");
992*5113495bSYour Name return 0;
993*5113495bSYour Name }
994*5113495bSYour Name
995*5113495bSYour Name return 1;
996*5113495bSYour Name }
997*5113495bSYour Name qdf_export_symbol(target_if_spectral_sops_sim_configure_params);
998*5113495bSYour Name
999*5113495bSYour Name uint32_t
target_if_spectral_sops_sim_get_params(void * arg,struct spectral_config * params)1000*5113495bSYour Name target_if_spectral_sops_sim_get_params(
1001*5113495bSYour Name void *arg, struct spectral_config *params)
1002*5113495bSYour Name {
1003*5113495bSYour Name struct target_if_spectral *spectral = NULL;
1004*5113495bSYour Name struct spectralsim_context *simctx = NULL;
1005*5113495bSYour Name spectral = (struct target_if_spectral *)arg;
1006*5113495bSYour Name
1007*5113495bSYour Name if (!param || !spectral) {
1008*5113495bSYour Name spectral_err("Spectral simulation: null params, param %pK, spectral %pK.",
1009*5113495bSYour Name param, spectral);
1010*5113495bSYour Name return 0;
1011*5113495bSYour Name }
1012*5113495bSYour Name
1013*5113495bSYour Name simctx = (struct spectralsim_context *)spectral->simctx;
1014*5113495bSYour Name if (!simctx) {
1015*5113495bSYour Name spectral_err("Spectral simulation: simctx pointer is null.");
1016*5113495bSYour Name return 0;
1017*5113495bSYour Name }
1018*5113495bSYour Name
1019*5113495bSYour Name if (!simctx->curr_reportset) {
1020*5113495bSYour Name spectral_warn("Spectral simulation: No configured reportset found.");
1021*5113495bSYour Name return 0;
1022*5113495bSYour Name }
1023*5113495bSYour Name
1024*5113495bSYour Name qdf_mem_copy(params, &simctx->curr_reportset->config, sizeof(*params));
1025*5113495bSYour Name
1026*5113495bSYour Name return 1;
1027*5113495bSYour Name }
1028*5113495bSYour Name qdf_export_symbol(target_if_spectral_sops_sim_get_params);
1029*5113495bSYour Name
1030*5113495bSYour Name #endif /* QCA_SUPPORT_SPECTRAL_SIMULATION */
1031