target_if_spectral_sim.c 26 KB

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