epping_main.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * Copyright (c) 2014-2019,2021 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /*========================================================================
  19. \file epping_main.c
  20. \brief WLAN End Point Ping test tool implementation
  21. ========================================================================*/
  22. /*--------------------------------------------------------------------------
  23. Include Files
  24. ------------------------------------------------------------------------*/
  25. #include <cds_api.h>
  26. #include <cds_sched.h>
  27. #include <linux/etherdevice.h>
  28. #include <linux/firmware.h>
  29. #include <wni_api.h>
  30. #include <wlan_ptt_sock_svc.h>
  31. #include <linux/wireless.h>
  32. #include <net/cfg80211.h>
  33. #include <linux/rtnetlink.h>
  34. #include <linux/semaphore.h>
  35. #include <linux/ctype.h>
  36. #include "bmi.h"
  37. #include "ol_fw.h"
  38. #include "ol_if_athvar.h"
  39. #include "hif.h"
  40. #include "epping_main.h"
  41. #include "epping_internal.h"
  42. #include "wlan_policy_mgr_api.h"
  43. #ifdef TIMER_MANAGER
  44. #define TIMER_MANAGER_STR " +TIMER_MANAGER"
  45. #else
  46. #define TIMER_MANAGER_STR ""
  47. #endif
  48. #ifdef MEMORY_DEBUG
  49. #define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
  50. #else
  51. #define MEMORY_DEBUG_STR ""
  52. #endif
  53. #ifdef HIF_SDIO
  54. #define WLAN_WAIT_TIME_WLANSTART 10000
  55. #else
  56. #define WLAN_WAIT_TIME_WLANSTART 2000
  57. #endif
  58. #ifdef WLAN_FEATURE_EPPING
  59. static struct epping_context *g_epping_ctx;
  60. /**
  61. * epping_open(): End point ping driver open Function
  62. *
  63. * This function is called by HDD to open epping module
  64. *
  65. *
  66. * return - 0 for success, negative for failure
  67. */
  68. int epping_open(void)
  69. {
  70. EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
  71. g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx));
  72. if (!g_epping_ctx)
  73. return -ENOMEM;
  74. g_epping_ctx->con_mode = cds_get_conparam();
  75. return 0;
  76. }
  77. /**
  78. * epping_disable(): End point ping driver disable Function
  79. *
  80. * This is the driver disable function - called by HDD to
  81. * disable epping module
  82. *
  83. * return: none
  84. */
  85. void epping_disable(void)
  86. {
  87. epping_context_t *epping_ctx;
  88. struct hif_opaque_softc *hif_ctx;
  89. HTC_HANDLE htc_handle;
  90. epping_ctx = g_epping_ctx;
  91. if (!epping_ctx) {
  92. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  93. "%s: error: epping_ctx = NULL", __func__);
  94. return;
  95. }
  96. hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
  97. if (!hif_ctx) {
  98. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  99. "%s: error: hif_ctx = NULL", __func__);
  100. return;
  101. }
  102. hif_disable_isr(hif_ctx);
  103. hif_reset_soc(hif_ctx);
  104. htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
  105. if (!htc_handle) {
  106. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  107. "%s: error: htc_handle = NULL", __func__);
  108. return;
  109. }
  110. htc_stop(htc_handle);
  111. epping_cookie_cleanup(epping_ctx);
  112. htc_destroy(htc_handle);
  113. if (epping_ctx->epping_adapter) {
  114. epping_destroy_adapter(epping_ctx->epping_adapter);
  115. epping_ctx->epping_adapter = NULL;
  116. }
  117. }
  118. /**
  119. * epping_close(): End point ping driver close Function
  120. *
  121. * This is the driver close function - called by HDD to close epping module
  122. *
  123. * return: none
  124. */
  125. void epping_close(void)
  126. {
  127. epping_context_t *to_free;
  128. if (!g_epping_ctx) {
  129. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  130. "%s: error: g_epping_ctx = NULL", __func__);
  131. return;
  132. }
  133. to_free = g_epping_ctx;
  134. g_epping_ctx = NULL;
  135. qdf_mem_free(to_free);
  136. }
  137. /**
  138. * epping_target_suspend_acknowledge() - process wow ack/nack from fw
  139. * @context: htc_init_info->context
  140. * @wow_nack: true when wow is rejected
  141. */
  142. static void epping_target_suspend_acknowledge(void *context, bool wow_nack)
  143. {
  144. if (!g_epping_ctx) {
  145. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  146. "%s: epping_ctx is NULL", __func__);
  147. return;
  148. }
  149. /* EPPING_TODO: do we need wow_nack? */
  150. g_epping_ctx->wow_nack = wow_nack;
  151. }
  152. #ifdef WLAN_FEATURE_BMI
  153. /**
  154. * epping_update_ol_config - API to update ol configuration parameters
  155. *
  156. * Return: void
  157. */
  158. static void epping_update_ol_config(void)
  159. {
  160. struct ol_config_info cfg;
  161. struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
  162. if (!ol_ctx)
  163. return;
  164. cfg.enable_self_recovery = 0;
  165. cfg.enable_uart_print = 0;
  166. cfg.enable_fw_log = 0;
  167. cfg.enable_ramdump_collection = 0;
  168. cfg.enable_lpass_support = 0;
  169. ol_init_ini_config(ol_ctx, &cfg);
  170. }
  171. static
  172. QDF_STATUS epping_bmi_download_fw(struct ol_context *ol_ctx)
  173. {
  174. epping_update_ol_config();
  175. /* Initialize BMI and Download firmware */
  176. if (bmi_download_firmware(ol_ctx)) {
  177. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
  178. "%s: BMI failed to download target", __func__);
  179. bmi_cleanup(ol_ctx);
  180. return QDF_STATUS_E_INVAL;
  181. }
  182. EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
  183. "%s: bmi_download_firmware done", __func__);
  184. return QDF_STATUS_SUCCESS;
  185. }
  186. #else
  187. static
  188. QDF_STATUS epping_bmi_download_fw(struct ol_context *ol_ctx)
  189. {
  190. return QDF_STATUS_SUCCESS;
  191. }
  192. #endif
  193. /**
  194. * epping_enable(): End point ping driver enable Function
  195. *
  196. * This is the driver enable function - called by HDD to enable
  197. * epping module
  198. *
  199. * return - 0 : success, negative: error
  200. */
  201. int epping_enable(struct device *parent_dev, bool rtnl_held)
  202. {
  203. int ret = 0;
  204. epping_context_t *epping_ctx = NULL;
  205. struct cds_context *p_cds_context = NULL;
  206. qdf_device_t qdf_ctx;
  207. struct htc_init_info htc_info;
  208. struct hif_opaque_softc *scn;
  209. tSirMacAddr adapter_macAddr;
  210. struct ol_context *ol_ctx = NULL;
  211. struct hif_target_info *tgt_info;
  212. EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
  213. p_cds_context = cds_get_global_context();
  214. if (!p_cds_context) {
  215. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  216. "%s: Failed cds_get_global_context", __func__);
  217. ret = -1;
  218. return ret;
  219. }
  220. epping_ctx = g_epping_ctx;
  221. if (!epping_ctx) {
  222. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  223. "%s: Failed to get epping_ctx", __func__);
  224. ret = -1;
  225. return ret;
  226. }
  227. epping_ctx->parent_dev = (void *)parent_dev;
  228. epping_get_dummy_mac_addr(adapter_macAddr);
  229. /* Initialize the timer module */
  230. qdf_timer_module_init();
  231. scn = cds_get_context(QDF_MODULE_ID_HIF);
  232. if (!scn) {
  233. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
  234. "%s: scn is null!", __func__);
  235. return A_ERROR;
  236. }
  237. tgt_info = hif_get_target_info_handle(scn);
  238. ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
  239. if (epping_bmi_download_fw(ol_ctx) != QDF_STATUS_SUCCESS)
  240. return A_ERROR;
  241. /* store target type and target version info in hdd ctx */
  242. epping_ctx->target_type = tgt_info->target_type;
  243. htc_info.pContext = NULL;
  244. htc_info.TargetFailure = ol_target_failure;
  245. htc_info.TargetSendSuspendComplete = epping_target_suspend_acknowledge;
  246. qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
  247. /* Create HTC */
  248. p_cds_context->htc_ctx = htc_create(scn, &htc_info, qdf_ctx,
  249. cds_get_conparam());
  250. if (!p_cds_context->htc_ctx) {
  251. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
  252. "%s: Failed to Create HTC", __func__);
  253. bmi_cleanup(ol_ctx);
  254. return A_ERROR;
  255. }
  256. epping_ctx->HTCHandle =
  257. cds_get_context(QDF_MODULE_ID_HTC);
  258. if (!epping_ctx->HTCHandle) {
  259. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  260. "%s: HTCHandle is NULL", __func__);
  261. return A_ERROR;
  262. }
  263. if (bmi_done(ol_ctx)) {
  264. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  265. "%s: Failed to complete BMI phase", __func__);
  266. goto error_end;
  267. }
  268. /* start HIF */
  269. if (htc_wait_target(epping_ctx->HTCHandle) != QDF_STATUS_SUCCESS) {
  270. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  271. "%s: htc_wait_target error", __func__);
  272. goto error_end;
  273. }
  274. EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__);
  275. ret = epping_connect_service(epping_ctx);
  276. if (ret != 0) {
  277. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  278. "%s: htc_wait_targetdone", __func__);
  279. goto error_end;
  280. }
  281. if (htc_start(epping_ctx->HTCHandle) != QDF_STATUS_SUCCESS)
  282. goto error_end;
  283. EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__);
  284. /* init the tx cookie resource */
  285. ret = epping_cookie_init(epping_ctx);
  286. if (ret < 0) {
  287. EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
  288. "%s: cookie init failed", __func__);
  289. htc_stop(epping_ctx->HTCHandle);
  290. epping_cookie_cleanup(epping_ctx);
  291. goto error_end;
  292. }
  293. EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__);
  294. return ret;
  295. error_end:
  296. htc_destroy(p_cds_context->htc_ctx);
  297. p_cds_context->htc_ctx = NULL;
  298. bmi_cleanup(ol_ctx);
  299. return A_ERROR;
  300. }
  301. void epping_enable_adapter(void)
  302. {
  303. epping_context_t *epping_ctx = g_epping_ctx;
  304. tSirMacAddr adapter_macaddr;
  305. if (!epping_ctx) {
  306. EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "epping context is NULL");
  307. return;
  308. }
  309. epping_get_dummy_mac_addr(adapter_macaddr);
  310. epping_ctx->epping_adapter = epping_add_adapter(epping_ctx,
  311. adapter_macaddr,
  312. QDF_STA_MODE, true);
  313. if (!epping_ctx->epping_adapter)
  314. EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "epping add adapter failed");
  315. }
  316. #endif