target_if_spectral_sim.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. /*
  2. * Copyright (c) 2015,2017 The Linux Foundation. All rights reserved.
  3. *
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for
  6. * any purpose with or without fee is hereby granted, provided that the
  7. * above copyright notice and this permission notice appear in all
  8. * copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  13. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  14. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  15. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  16. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. * PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. #ifdef QCA_SUPPORT_SPECTRAL_SIMULATION
  20. #include "target_if_spectral.h"
  21. #include "target_if_spectral_sim.h"
  22. #include "target_if_spectral_sim_int.h"
  23. #include "_ieee80211.h"
  24. #include "ieee80211_api.h"
  25. #include "ieee80211_defines.h"
  26. #include "qdf_types.h"
  27. #include "ieee80211_var.h"
  28. #include <wlan_mlme_dispatcher.h>
  29. /* Helper functions */
  30. int tif_populate_reportset_fromfile(ath_spectralsim_reportset * reportset,
  31. enum phy_ch_width width,
  32. bool is_80_80);
  33. static int populate_report_static_gen2(ath_spectralsim_report *report,
  34. enum phy_ch_width width,
  35. bool is_80_80);
  36. static int populate_report_static_gen3(ath_spectralsim_report *report,
  37. enum phy_ch_width width,
  38. bool is_80_80);
  39. static void depopulate_report(ath_spectralsim_report *report);
  40. static int populate_reportset_static(ath_spectralsim_context *simctx,
  41. ath_spectralsim_reportset *reportset,
  42. enum phy_ch_width width,
  43. bool is_80_80);
  44. static void depopulate_reportset(ath_spectralsim_reportset *reportset);
  45. static int populate_simdata(ath_spectralsim_context *simctx);
  46. static void depopulate_simdata(ath_spectralsim_context *simctx);
  47. static OS_TIMER_FUNC(spectral_sim_phyerrdelivery_handler);
  48. /* Static configuration.
  49. * For now, we will be having a single configuration per BW, and a single
  50. * report per configuration (since we need the data only for ensuring correct
  51. * format handling).
  52. *
  53. * Extend this for more functionality if required in the future.
  54. */
  55. /* Statically populate simulation data for one report. */
  56. static int populate_report_static_gen2(ath_spectralsim_report *report,
  57. enum phy_ch_width width,
  58. bool is_80_80)
  59. {
  60. qdf_assert_always(report);
  61. switch (width) {
  62. case CH_WIDTH_20MHZ:
  63. report->data = NULL;
  64. report->data = (u_int8_t *)
  65. qdf_mem_malloc(sizeof(reportdata_20_gen2));
  66. if (!report->data) {
  67. qdf_print("Spectral simulation: Could not allocate memory for "
  68. "report data\n");
  69. goto bad;
  70. }
  71. report->datasize = sizeof(reportdata_20_gen2);
  72. qdf_mem_copy(report->data,
  73. reportdata_20_gen2, report->datasize);
  74. qdf_mem_copy(&report->rfqual_info,
  75. &rfqual_info_20, sizeof(report->rfqual_info));
  76. qdf_mem_copy(&report->chan_info,
  77. &chan_info_20, sizeof(report->chan_info));
  78. break;
  79. case CH_WIDTH_40MHZ:
  80. report->data = NULL;
  81. report->data = (u_int8_t *)
  82. qdf_mem_malloc(sizeof(reportdata_40_gen2));
  83. if (!report->data) {
  84. qdf_print("Spectral simulation: Could not allocate memory for "
  85. "report data\n");
  86. goto bad;
  87. }
  88. report->datasize = sizeof(reportdata_40_gen2);
  89. qdf_mem_copy(report->data,
  90. reportdata_40_gen2, report->datasize);
  91. qdf_mem_copy(&report->rfqual_info,
  92. &rfqual_info_40, sizeof(report->rfqual_info));
  93. qdf_mem_copy(&report->chan_info,
  94. &chan_info_40, sizeof(report->chan_info));
  95. break;
  96. case CH_WIDTH_80MHZ:
  97. report->data = NULL;
  98. report->data = (u_int8_t *)
  99. qdf_mem_malloc(sizeof(reportdata_80_gen2));
  100. if (!report->data) {
  101. qdf_print("Spectral simulation: Could not allocate memory for "
  102. "report data\n");
  103. goto bad;
  104. }
  105. report->datasize = sizeof(reportdata_80_gen2);
  106. qdf_mem_copy(report->data,
  107. reportdata_80_gen2, report->datasize);
  108. qdf_mem_copy(&report->rfqual_info,
  109. &rfqual_info_80, sizeof(report->rfqual_info));
  110. qdf_mem_copy(&report->chan_info,
  111. &chan_info_80, sizeof(report->chan_info));
  112. break;
  113. case CH_WIDTH_160MHZ:
  114. if (is_80_80) {
  115. report->data = NULL;
  116. report->data = (u_int8_t *)
  117. qdf_mem_malloc(sizeof(reportdata_80_80_gen2));
  118. if (!report->data) {
  119. qdf_print("Spectral simulation: Could not allocate "
  120. "memory for report data\n");
  121. goto bad;
  122. }
  123. report->datasize = sizeof(reportdata_80_80_gen2);
  124. qdf_mem_copy(report->data,
  125. reportdata_80_80_gen2, report->datasize);
  126. qdf_mem_copy(&report->rfqual_info,
  127. &rfqual_info_80_80, sizeof(report->rfqual_info));
  128. qdf_mem_copy(&report->chan_info,
  129. &chan_info_80_80, sizeof(report->chan_info));
  130. } else {
  131. report->data = NULL;
  132. report->data = (u_int8_t *)
  133. qdf_mem_malloc(sizeof(reportdata_160_gen2));
  134. if (!report->data) {
  135. qdf_print("Spectral simulation: Could not allocate "
  136. "memory for report data\n");
  137. goto bad;
  138. }
  139. report->datasize = sizeof(reportdata_160_gen2);
  140. qdf_mem_copy(report->data,
  141. reportdata_160_gen2, report->datasize);
  142. qdf_mem_copy(&report->rfqual_info,
  143. &rfqual_info_160, sizeof(report->rfqual_info));
  144. qdf_mem_copy(&report->chan_info,
  145. &chan_info_160, sizeof(report->chan_info));
  146. }
  147. break;
  148. default:
  149. qdf_print("Unhandled width. Please correct. Asserting\n");
  150. qdf_assert_always(0);
  151. }
  152. return 0;
  153. bad:
  154. return -EPERM;
  155. }
  156. /* Statically populate simulation data for one report. */
  157. static int populate_report_static_gen3(ath_spectralsim_report *report,
  158. enum phy_ch_width width,
  159. bool is_80_80)
  160. {
  161. qdf_assert_always(report);
  162. switch (width) {
  163. case CH_WIDTH_20MHZ:
  164. report->data = NULL;
  165. report->data = (u_int8_t *)
  166. qdf_mem_malloc(sizeof(reportdata_20_gen3));
  167. if (!report->data) {
  168. qdf_print("Spectral simulation: Could not allocate "
  169. "memory for report data\n");
  170. goto bad;
  171. }
  172. report->datasize = sizeof(reportdata_20_gen3);
  173. qdf_mem_copy(report->data,
  174. reportdata_20_gen3, report->datasize);
  175. qdf_mem_copy(&report->rfqual_info,
  176. &rfqual_info_20, sizeof(report->rfqual_info));
  177. qdf_mem_copy(&report->chan_info,
  178. &chan_info_20, sizeof(report->chan_info));
  179. break;
  180. case CH_WIDTH_40MHZ:
  181. report->data = NULL;
  182. report->data = (u_int8_t *)
  183. qdf_mem_malloc(sizeof(reportdata_40_gen3));
  184. if (!report->data) {
  185. qdf_print("Spectral simulation: Could not allocate "
  186. "memory for report data\n");
  187. goto bad;
  188. }
  189. report->datasize = sizeof(reportdata_40_gen3);
  190. qdf_mem_copy(report->data,
  191. reportdata_40_gen3, report->datasize);
  192. qdf_mem_copy(&report->rfqual_info,
  193. &rfqual_info_40, sizeof(report->rfqual_info));
  194. qdf_mem_copy(&report->chan_info,
  195. &chan_info_40, sizeof(report->chan_info));
  196. break;
  197. case CH_WIDTH_80MHZ:
  198. report->data = NULL;
  199. report->data = (u_int8_t *)
  200. qdf_mem_malloc(sizeof(reportdata_80_gen3));
  201. if (!report->data) {
  202. qdf_print("Spectral simulation: Could not allocate memory for "
  203. "report data\n");
  204. goto bad;
  205. }
  206. report->datasize = sizeof(reportdata_80_gen3);
  207. qdf_mem_copy(report->data,
  208. reportdata_80_gen3, report->datasize);
  209. qdf_mem_copy(&report->rfqual_info,
  210. &rfqual_info_80, sizeof(report->rfqual_info));
  211. qdf_mem_copy(&report->chan_info,
  212. &chan_info_80, sizeof(report->chan_info));
  213. break;
  214. case CH_WIDTH_160MHZ:
  215. if (is_80_80) {
  216. report->data = NULL;
  217. report->data = (u_int8_t *)
  218. qdf_mem_malloc(sizeof(reportdata_80_80_gen3));
  219. if (!report->data) {
  220. qdf_print("Spectral simulation: Could not allocate "
  221. "memory for report data\n");
  222. goto bad;
  223. }
  224. report->datasize = sizeof(reportdata_80_80_gen3);
  225. qdf_mem_copy(report->data,
  226. reportdata_80_80_gen3, report->datasize);
  227. qdf_mem_copy(&report->rfqual_info,
  228. &rfqual_info_80_80, sizeof(report->rfqual_info));
  229. qdf_mem_copy(&report->chan_info,
  230. &chan_info_80_80, sizeof(report->chan_info));
  231. } else {
  232. report->data = NULL;
  233. report->data = (u_int8_t *)
  234. qdf_mem_malloc(sizeof(reportdata_160_gen3));
  235. if (!report->data) {
  236. qdf_print("Spectral simulation: Could not allocate "
  237. "memory for report data\n");
  238. goto bad;
  239. }
  240. report->datasize = sizeof(reportdata_160_gen3);
  241. qdf_mem_copy(report->data,
  242. reportdata_160_gen3, report->datasize);
  243. qdf_mem_copy(&report->rfqual_info,
  244. &rfqual_info_160, sizeof(report->rfqual_info));
  245. qdf_mem_copy(&report->chan_info,
  246. &chan_info_160, sizeof(report->chan_info));
  247. }
  248. break;
  249. default:
  250. qdf_print("Unhandled width. Please correct. Asserting\n");
  251. qdf_assert_always(0);
  252. }
  253. return 0;
  254. bad:
  255. return -EPERM;
  256. }
  257. static void depopulate_report(ath_spectralsim_report *report)
  258. {
  259. if (!report)
  260. return;
  261. if (report->data) {
  262. qdf_mem_free(report->data);
  263. report->data = NULL;
  264. report->datasize = 0;
  265. }
  266. }
  267. /* Statically populate simulation data for a given configuration. */
  268. static int populate_reportset_static(ath_spectralsim_context *simctx,
  269. ath_spectralsim_reportset *reportset,
  270. enum phy_ch_width width,
  271. bool is_80_80)
  272. {
  273. int ret = 0;
  274. ath_spectralsim_report *report = NULL;
  275. qdf_assert_always(reportset);
  276. reportset->headreport = NULL;
  277. reportset->curr_report = NULL;
  278. /* For now, we populate only one report */
  279. report = (ath_spectralsim_report *)
  280. qdf_mem_malloc(sizeof(ath_spectralsim_report));
  281. if (!report) {
  282. qdf_print("Spectral simulation: Could not allocate memory "
  283. "for report.\n");
  284. goto bad;
  285. }
  286. qdf_mem_zero(report, sizeof(*report));
  287. switch (width) {
  288. case CH_WIDTH_20MHZ:
  289. qdf_mem_copy(&reportset->config,
  290. &config_20_1, sizeof(reportset->config));
  291. ret = simctx->populate_report_static(report, CH_WIDTH_20MHZ, 0);
  292. if (ret != 0)
  293. goto bad;
  294. report->next = NULL;
  295. reportset->headreport = report;
  296. break;
  297. case CH_WIDTH_40MHZ:
  298. qdf_mem_copy(&reportset->config,
  299. &config_40_1, sizeof(reportset->config));
  300. ret = simctx->populate_report_static(report, CH_WIDTH_40MHZ, 0);
  301. if (ret != 0)
  302. goto bad;
  303. report->next = NULL;
  304. reportset->headreport = report;
  305. break;
  306. case CH_WIDTH_80MHZ:
  307. qdf_mem_copy(&reportset->config,
  308. &config_80_1, sizeof(reportset->config));
  309. ret = simctx->populate_report_static(report, CH_WIDTH_80MHZ, 0);
  310. if (ret != 0)
  311. goto bad;
  312. report->next = NULL;
  313. reportset->headreport = report;
  314. break;
  315. case CH_WIDTH_160MHZ:
  316. if (is_80_80) {
  317. qdf_mem_copy(&reportset->config,
  318. &config_80_80_1, sizeof(reportset->config));
  319. ret = simctx->populate_report_static(
  320. report,
  321. CH_WIDTH_160MHZ,
  322. 1);
  323. if (ret != 0)
  324. goto bad;
  325. report->next = NULL;
  326. reportset->headreport = report;
  327. } else {
  328. qdf_mem_copy(&reportset->config,
  329. &config_160_1, sizeof(reportset->config));
  330. ret = simctx->populate_report_static(
  331. report,
  332. CH_WIDTH_160MHZ,
  333. 0);
  334. if (ret != 0)
  335. goto bad;
  336. report->next = NULL;
  337. reportset->headreport = report;
  338. }
  339. break;
  340. default:
  341. qdf_print("Unhandled width. Please rectify.\n");
  342. qdf_assert_always(0);
  343. };
  344. reportset->curr_report = reportset->headreport;
  345. return 0;
  346. bad:
  347. depopulate_reportset(reportset);
  348. return -EPERM;
  349. }
  350. static void depopulate_reportset(ath_spectralsim_reportset *reportset)
  351. {
  352. ath_spectralsim_report *curr_report = NULL;
  353. ath_spectralsim_report *next_report = NULL;
  354. if (!reportset)
  355. return;
  356. curr_report = reportset->headreport;
  357. while (curr_report) {
  358. next_report = curr_report->next;
  359. depopulate_report(curr_report);
  360. qdf_mem_free(curr_report);
  361. curr_report = next_report;
  362. }
  363. }
  364. /* Populate simulation data for a given bandwidth by loading from a file.
  365. * This is a place-holder only. To be implemented in the future on a need
  366. * basis.
  367. *
  368. * A different file per bandwidth is suggested for better segregation of data
  369. * sets (since data is likely to be very different across BWs).
  370. */
  371. int tif_populate_reportset_fromfile(ath_spectralsim_reportset *reportset,
  372. enum phy_ch_width width,
  373. bool is_80_80)
  374. {
  375. qdf_print("%s: To be implemented if required\n", __func__);
  376. return 0;
  377. }
  378. /* Populate simulation data */
  379. static int populate_simdata(ath_spectralsim_context *simctx)
  380. {
  381. /* For now, we use static population. Switch to loading from a file if
  382. * needed in the future.
  383. */
  384. simctx->bw20_headreportset = NULL;
  385. SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
  386. simctx->bw20_headreportset,
  387. CH_WIDTH_20MHZ,
  388. 0);
  389. simctx->bw40_headreportset = NULL;
  390. SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
  391. simctx->bw40_headreportset,
  392. CH_WIDTH_40MHZ,
  393. 0);
  394. simctx->bw80_headreportset = NULL;
  395. SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
  396. simctx->bw80_headreportset,
  397. CH_WIDTH_80MHZ,
  398. 0);
  399. simctx->bw160_headreportset = NULL;
  400. SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
  401. simctx->bw160_headreportset,
  402. CH_WIDTH_160MHZ,
  403. 0);
  404. simctx->bw80_80_headreportset = NULL;
  405. SPECTRAL_SIM_REPORTSET_ALLOCPOPL_SINGLE(simctx,
  406. simctx->bw80_80_headreportset,
  407. CH_WIDTH_160MHZ,
  408. 1);
  409. simctx->curr_reportset = NULL;
  410. simctx->is_enabled = false;
  411. simctx->is_active = false;
  412. simctx->ssim_starting_tsf64 = 0;
  413. simctx->ssim_count = 0;
  414. simctx->ssim_period_ms = 0;
  415. return 0;
  416. }
  417. static void depopulate_simdata(ath_spectralsim_context *simctx)
  418. {
  419. if (!simctx)
  420. return;
  421. SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw20_headreportset);
  422. SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw40_headreportset);
  423. SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw80_headreportset);
  424. SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw160_headreportset);
  425. SPECTRAL_SIM_REPORTSET_DEPOPLFREE_LIST(simctx->bw80_80_headreportset);
  426. }
  427. static
  428. OS_TIMER_FUNC(spectral_sim_phyerrdelivery_handler)
  429. {
  430. struct target_if_spectral *spectral = NULL;
  431. ath_spectralsim_context *simctx = NULL;
  432. ath_spectralsim_reportset *curr_reportset = NULL;
  433. ath_spectralsim_report *curr_report = NULL;
  434. struct target_if_spectral_acs_stats acs_stats;
  435. u_int64_t curr_tsf64 = 0;
  436. struct target_if_spectral_ops *p_sops;
  437. OS_GET_TIMER_ARG(spectral, struct target_if_spectral *);
  438. qdf_assert_always(spectral);
  439. p_sops = GET_TIF_SPECTRAL_OPS(spectral);
  440. qdf_assert_always(spectral);
  441. simctx = (ath_spectralsim_context *)spectral->simctx;
  442. qdf_assert_always(simctx);
  443. if (!simctx->is_active)
  444. return;
  445. curr_reportset = simctx->curr_reportset;
  446. qdf_assert_always(curr_reportset);
  447. curr_report = curr_reportset->curr_report;
  448. qdf_assert_always(curr_report);
  449. qdf_assert_always(curr_reportset->headreport);
  450. /* We use a simulation TSF since in offload architectures we can't
  451. * expect to
  452. * get an accurate current TSF from HW.
  453. * In case of TSF wrap over, we'll use it as-is for now since the
  454. * simulation
  455. * is intended only for format verification.
  456. */
  457. curr_tsf64 = simctx->ssim_starting_tsf64 +
  458. ((simctx->ssim_period_ms * simctx->ssim_count) * 1000);
  459. p_sops->spectral_process_phyerr(spectral,
  460. curr_report->data,
  461. curr_report->datasize,
  462. &curr_report->rfqual_info,
  463. &curr_report->chan_info,
  464. curr_tsf64,
  465. &acs_stats);
  466. simctx->ssim_count++;
  467. if (curr_report->next)
  468. curr_reportset->curr_report = curr_report->next;
  469. else
  470. curr_reportset->curr_report = curr_reportset->headreport;
  471. if (curr_reportset->config.ss_count != 0 &&
  472. simctx->ssim_count == curr_reportset->config.ss_count) {
  473. tif_spectral_sim_stop_spectral_scan(spectral);
  474. } else {
  475. qdf_timer_start(&simctx->ssim_pherrdelivery_timer,
  476. simctx->ssim_period_ms);
  477. }
  478. }
  479. /* Module services */
  480. int target_if_spectral_sim_attach(struct target_if_spectral *spectral)
  481. {
  482. ath_spectralsim_context *simctx = NULL;
  483. qdf_assert_always(spectral);
  484. simctx = (ath_spectralsim_context *)
  485. qdf_mem_malloc(sizeof(ath_spectralsim_context));
  486. if (!simctx) {
  487. qdf_print("Spectral simulation: Could not allocate memory for "
  488. "context\n");
  489. return -EPERM;
  490. }
  491. qdf_mem_zero(simctx, sizeof(*simctx));
  492. spectral->simctx = simctx;
  493. if (spectral->spectral_gen == SPECTRAL_GEN2)
  494. simctx->populate_report_static = populate_report_static_gen2;
  495. else if (spectral->spectral_gen == SPECTRAL_GEN3)
  496. simctx->populate_report_static = populate_report_static_gen3;
  497. if (populate_simdata(simctx) != 0) {
  498. qdf_mem_free(simctx);
  499. spectral->simctx = NULL;
  500. qdf_print("Spectral simulation attach failed\n");
  501. return -EPERM;
  502. }
  503. qdf_timer_init(NULL,
  504. &simctx->ssim_pherrdelivery_timer,
  505. spectral_sim_phyerrdelivery_handler,
  506. (void *)(spectral),
  507. QDF_TIMER_TYPE_WAKE_APPS);
  508. qdf_print("Spectral simulation attached\n");
  509. return 0;
  510. }
  511. void target_if_spectral_sim_detach(struct target_if_spectral *spectral)
  512. {
  513. ath_spectralsim_context *simctx = NULL;
  514. qdf_assert_always(spectral);
  515. simctx = (ath_spectralsim_context *)spectral->simctx;
  516. qdf_assert_always(simctx);
  517. qdf_timer_free(&simctx->ssim_pherrdelivery_timer);
  518. depopulate_simdata(simctx);
  519. qdf_mem_free(simctx);
  520. spectral->simctx = NULL;
  521. qdf_print("Spectral simulation detached\n");
  522. }
  523. u_int32_t tif_spectral_sim_is_spectral_active(void *arg)
  524. {
  525. struct target_if_spectral *spectral = NULL;
  526. ath_spectralsim_context *simctx = NULL;
  527. spectral = (struct target_if_spectral *)arg;
  528. qdf_assert_always(spectral);
  529. simctx = (ath_spectralsim_context *)spectral->simctx;
  530. qdf_assert_always(simctx);
  531. return simctx->is_active;
  532. }
  533. EXPORT_SYMBOL(tif_spectral_sim_is_spectral_active);
  534. u_int32_t tif_spectral_sim_is_spectral_enabled(void *arg)
  535. {
  536. struct target_if_spectral *spectral = NULL;
  537. ath_spectralsim_context *simctx = NULL;
  538. spectral = (struct target_if_spectral *)arg;
  539. qdf_assert_always(spectral);
  540. simctx = (ath_spectralsim_context *)spectral->simctx;
  541. qdf_assert_always(simctx);
  542. return simctx->is_enabled;
  543. }
  544. EXPORT_SYMBOL(tif_spectral_sim_is_spectral_enabled);
  545. u_int32_t tif_spectral_sim_start_spectral_scan(void *arg)
  546. {
  547. struct target_if_spectral *spectral = NULL;
  548. ath_spectralsim_context *simctx = NULL;
  549. spectral = (struct target_if_spectral *)arg;
  550. qdf_assert_always(spectral);
  551. simctx = (ath_spectralsim_context *)spectral->simctx;
  552. qdf_assert_always(simctx);
  553. if (!simctx->curr_reportset) {
  554. qdf_print("Spectral simulation: No current report set "
  555. "configured - unable to start simulated Spectral "
  556. "scan\n");
  557. return 0;
  558. }
  559. if (!simctx->curr_reportset->curr_report) {
  560. qdf_print("Spectral simulation: No report data instances "
  561. "populated - unable to start simulated Spectral "
  562. "scan\n");
  563. return 0;
  564. }
  565. if (!simctx->is_enabled)
  566. simctx->is_enabled = true;
  567. simctx->is_active = true;
  568. /* Hardcoding current time as zero since it is simulation */
  569. simctx->ssim_starting_tsf64 = 0;
  570. simctx->ssim_count = 0;
  571. /* TODO: Support high resolution timer in microseconds if required, so
  572. * that
  573. * we can support default periods such as ~200 us. For now, we use 1
  574. * millisecond since the current use case for the simulation is to
  575. * validate
  576. * formats rather than have a time dependent classification.
  577. */
  578. simctx->ssim_period_ms = 1;
  579. qdf_timer_start(&simctx->ssim_pherrdelivery_timer,
  580. simctx->ssim_period_ms);
  581. return 1;
  582. }
  583. EXPORT_SYMBOL(tif_spectral_sim_start_spectral_scan);
  584. u_int32_t tif_spectral_sim_stop_spectral_scan(void *arg)
  585. {
  586. struct target_if_spectral *spectral = NULL;
  587. ath_spectralsim_context *simctx = NULL;
  588. spectral = (struct target_if_spectral *)arg;
  589. qdf_assert_always(spectral);
  590. simctx = (ath_spectralsim_context *)spectral->simctx;
  591. qdf_assert_always(simctx);
  592. qdf_timer_stop(&simctx->ssim_pherrdelivery_timer);
  593. simctx->is_active = false;
  594. simctx->is_enabled = false;
  595. simctx->ssim_starting_tsf64 = 0;
  596. simctx->ssim_count = 0;
  597. simctx->ssim_period_ms = 0;
  598. return 1;
  599. }
  600. EXPORT_SYMBOL(tif_spectral_sim_stop_spectral_scan);
  601. u_int32_t tif_spectral_sim_configure_params(
  602. void *arg,
  603. struct spectral_config *params)
  604. {
  605. struct target_if_spectral *spectral = NULL;
  606. ath_spectralsim_context *simctx = NULL;
  607. enum wlan_phymode phymode;
  608. u_int8_t bw;
  609. ath_spectralsim_reportset *des_headreportset = NULL;
  610. ath_spectralsim_reportset *temp_reportset = NULL;
  611. bool is_invalid_width = false;
  612. struct wlan_objmgr_vdev *vdev = NULL;
  613. qdf_assert_always(params);
  614. #ifdef SPECTRAL_SIM_DUMP_PARAM_DATA
  615. {
  616. int i = 0;
  617. qdf_print("\n");
  618. qdf_print("Spectral simulation: Param data dump:\n"
  619. "ss_fft_period=%hu\n"
  620. "ss_period=%hu\n"
  621. "ss_count=%hu\n"
  622. "ss_short_report=%hu\n"
  623. "radar_bin_thresh_sel=%hhu\n"
  624. "ss_spectral_pri=%hu\n"
  625. "ss_fft_size=%hu\n"
  626. "ss_gc_ena=%hu\n"
  627. "ss_restart_ena=%hu\n"
  628. "ss_noise_floor_ref=%hu\n"
  629. "ss_init_delay=%hu\n"
  630. "ss_nb_tone_thr=%hu\n"
  631. "ss_str_bin_thr=%hu\n"
  632. "ss_wb_rpt_mode=%hu\n"
  633. "ss_rssi_rpt_mode=%hu\n"
  634. "ss_rssi_thr=%hu\n"
  635. "ss_pwr_format=%hu\n"
  636. "ss_rpt_mode=%hu\n"
  637. "ss_bin_scale=%hu\n"
  638. "ss_dbm_adj=%hu\n"
  639. "ss_chn_mask=%hu\n"
  640. "ss_nf_temp_data=%d\n",
  641. params->ss_fft_period,
  642. params->ss_period,
  643. params->ss_count,
  644. params->ss_short_report,
  645. params->radar_bin_thresh_sel,
  646. params->ss_spectral_pri,
  647. params->ss_fft_size,
  648. params->ss_gc_ena,
  649. params->ss_restart_ena,
  650. params->ss_noise_floor_ref,
  651. params->ss_init_delay,
  652. params->ss_nb_tone_thr,
  653. params->ss_str_bin_thr,
  654. params->ss_wb_rpt_mode,
  655. params->ss_rssi_rpt_mode,
  656. params->ss_rssi_thr,
  657. params->ss_pwr_format,
  658. params->ss_rpt_mode,
  659. params->ss_bin_scale,
  660. params->ss_dbm_adj,
  661. params->ss_chn_mask,
  662. params->ss_nf_temp_data);
  663. for (i = 0; i < AH_MAX_CHAINS * 2; i++)
  664. qdf_print("ss_nf_cal[%d]=%hhd\n", i, params->ss_nf_cal[i]);
  665. for (i = 0; i < AH_MAX_CHAINS * 2; i++)
  666. qdf_print("ss_nf_pwr[%d]=%hhd\n", i, params->ss_nf_pwr[i]);
  667. qdf_print("\n");
  668. }
  669. #endif /* SPECTRAL_SIM_DUMP_PARAM_DATA */
  670. spectral = (struct target_if_spectral *)arg;
  671. qdf_assert_always(spectral);
  672. simctx = (ath_spectralsim_context *)spectral->simctx;
  673. qdf_assert_always(simctx);
  674. vdev = target_if_spectral_get_vdev(spectral);
  675. if (!vdev) {
  676. qdf_print("Spectral simulation: No VAPs found - not proceeding"
  677. " with param config.\n");
  678. return 0;
  679. }
  680. bw = target_if_vdev_get_ch_width(vdev);
  681. switch (bw) {
  682. case CH_WIDTH_20MHZ:
  683. des_headreportset = simctx->bw20_headreportset;
  684. break;
  685. case CH_WIDTH_40MHZ:
  686. des_headreportset = simctx->bw40_headreportset;
  687. break;
  688. case CH_WIDTH_80MHZ:
  689. des_headreportset = simctx->bw80_headreportset;
  690. break;
  691. case CH_WIDTH_160MHZ:
  692. phymode = wlan_vdev_get_phymode(vdev);
  693. if (phymode == WLAN_PHYMODE_11AC_VHT160) {
  694. des_headreportset = simctx->bw160_headreportset;
  695. } else if (phymode == WLAN_PHYMODE_11AC_VHT80_80) {
  696. des_headreportset = simctx->bw80_80_headreportset;
  697. } else {
  698. qdf_print("Spectral simulation: Unexpected PHY mode %u"
  699. " found for width 160 MHz...asserting.\n",
  700. phymode);
  701. qdf_assert_always(0);
  702. }
  703. break;
  704. case IEEE80211_CWM_WIDTHINVALID:
  705. qdf_print("Spectral simulation: Invalid width configured - not"
  706. " proceeding with param config.\n");
  707. is_invalid_width = true;
  708. default:
  709. qdf_print("Spectral simulation: Unknown width %u...asserting\n"
  710. , bw);
  711. qdf_assert_always(0);
  712. break;
  713. }
  714. wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
  715. if (is_invalid_width)
  716. return 0;
  717. if (!des_headreportset) {
  718. qdf_print("Spectral simulation: No simulation data present for"
  719. " configured bandwidth/PHY mode - unable to proceed "
  720. " with param config.\n");
  721. return 0;
  722. }
  723. simctx->curr_reportset = NULL;
  724. temp_reportset = des_headreportset;
  725. while (temp_reportset) {
  726. if (qdf_mem_cmp(&temp_reportset->config,
  727. params, sizeof(struct spectral_config)) == 0) {
  728. /* Found a matching config. We are done. */
  729. simctx->curr_reportset = temp_reportset;
  730. break;
  731. }
  732. temp_reportset = temp_reportset->next;
  733. }
  734. if (!simctx->curr_reportset) {
  735. qdf_print("Spectral simulation: No simulation data present for"
  736. " desired Spectral configuration - unable to proceed"
  737. " with param config.\n");
  738. return 0;
  739. }
  740. if (!simctx->curr_reportset->curr_report) {
  741. qdf_print("Spectral simulation: No report data instances "
  742. "populated for desired Spectral configuration - "
  743. "unable to proceed with param config\n");
  744. return 0;
  745. }
  746. return 1;
  747. }
  748. EXPORT_SYMBOL(tif_spectral_sim_configure_params);
  749. u_int32_t tif_spectral_sim_get_params(
  750. void *arg,
  751. struct spectral_config *params)
  752. {
  753. struct target_if_spectral *spectral = NULL;
  754. ath_spectralsim_context *simctx = NULL;
  755. qdf_assert_always(params);
  756. spectral = (struct target_if_spectral *)arg;
  757. qdf_assert_always(spectral);
  758. simctx = (ath_spectralsim_context *)spectral->simctx;
  759. qdf_assert_always(simctx);
  760. if (!simctx->curr_reportset) {
  761. qdf_print("Spectral simulation: No configured reportset found.\n");
  762. return 0;
  763. }
  764. qdf_mem_copy(params, &simctx->curr_reportset->config, sizeof(*params));
  765. return 1;
  766. }
  767. EXPORT_SYMBOL(tif_spectral_sim_get_params);
  768. #endif /* QCA_SUPPORT_SPECTRAL_SIMULATION */