hif_main.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /*
  2. * Copyright (c) 2015-2018 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. #include "targcfg.h"
  19. #include "qdf_lock.h"
  20. #include "qdf_status.h"
  21. #include "qdf_status.h"
  22. #include <qdf_atomic.h> /* qdf_atomic_read */
  23. #include <targaddrs.h>
  24. #include "hif_io32.h"
  25. #include <hif.h>
  26. #include <target_type.h>
  27. #include "regtable.h"
  28. #define ATH_MODULE_NAME hif
  29. #include <a_debug.h>
  30. #include "hif_main.h"
  31. #include "hif_hw_version.h"
  32. #if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB)
  33. #include "ce_tasklet.h"
  34. #include "ce_api.h"
  35. #endif
  36. #include "qdf_trace.h"
  37. #include "qdf_status.h"
  38. #include "hif_debug.h"
  39. #include "mp_dev.h"
  40. #ifdef QCA_WIFI_QCA8074
  41. #include "hal_api.h"
  42. #endif
  43. #include "hif_napi.h"
  44. #include "hif_unit_test_suspend_i.h"
  45. #include "qdf_module.h"
  46. void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start)
  47. {
  48. hif_trigger_dump(hif_ctx, cmd_id, start);
  49. }
  50. /**
  51. * hif_get_target_id(): hif_get_target_id
  52. *
  53. * Return the virtual memory base address to the caller
  54. *
  55. * @scn: hif_softc
  56. *
  57. * Return: A_target_id_t
  58. */
  59. A_target_id_t hif_get_target_id(struct hif_softc *scn)
  60. {
  61. return scn->mem;
  62. }
  63. /**
  64. * hif_get_targetdef(): hif_get_targetdef
  65. * @scn: scn
  66. *
  67. * Return: void *
  68. */
  69. void *hif_get_targetdef(struct hif_opaque_softc *hif_ctx)
  70. {
  71. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  72. return scn->targetdef;
  73. }
  74. /**
  75. * hif_vote_link_down(): unvote for link up
  76. *
  77. * Call hif_vote_link_down to release a previous request made using
  78. * hif_vote_link_up. A hif_vote_link_down call should only be made
  79. * after a corresponding hif_vote_link_up, otherwise you could be
  80. * negating a vote from another source. When no votes are present
  81. * hif will not guarantee the linkstate after hif_bus_suspend.
  82. *
  83. * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
  84. * and initialization deinitialization sequencences.
  85. *
  86. * Return: n/a
  87. */
  88. void hif_vote_link_down(struct hif_opaque_softc *hif_ctx)
  89. {
  90. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  91. QDF_BUG(scn);
  92. scn->linkstate_vote--;
  93. if (scn->linkstate_vote == 0)
  94. hif_bus_prevent_linkdown(scn, false);
  95. }
  96. /**
  97. * hif_vote_link_up(): vote to prevent bus from suspending
  98. *
  99. * Makes hif guarantee that fw can message the host normally
  100. * durring suspend.
  101. *
  102. * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
  103. * and initialization deinitialization sequencences.
  104. *
  105. * Return: n/a
  106. */
  107. void hif_vote_link_up(struct hif_opaque_softc *hif_ctx)
  108. {
  109. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  110. QDF_BUG(scn);
  111. scn->linkstate_vote++;
  112. if (scn->linkstate_vote == 1)
  113. hif_bus_prevent_linkdown(scn, true);
  114. }
  115. /**
  116. * hif_can_suspend_link(): query if hif is permitted to suspend the link
  117. *
  118. * Hif will ensure that the link won't be suspended if the upperlayers
  119. * don't want it to.
  120. *
  121. * SYNCHRONIZATION: MC thread is stopped before bus suspend thus
  122. * we don't need extra locking to ensure votes dont change while
  123. * we are in the process of suspending or resuming.
  124. *
  125. * Return: false if hif will guarantee link up durring suspend.
  126. */
  127. bool hif_can_suspend_link(struct hif_opaque_softc *hif_ctx)
  128. {
  129. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  130. QDF_BUG(scn);
  131. return scn->linkstate_vote == 0;
  132. }
  133. /**
  134. * hif_hia_item_address(): hif_hia_item_address
  135. * @target_type: target_type
  136. * @item_offset: item_offset
  137. *
  138. * Return: n/a
  139. */
  140. uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
  141. {
  142. switch (target_type) {
  143. case TARGET_TYPE_AR6002:
  144. return AR6002_HOST_INTEREST_ADDRESS + item_offset;
  145. case TARGET_TYPE_AR6003:
  146. return AR6003_HOST_INTEREST_ADDRESS + item_offset;
  147. case TARGET_TYPE_AR6004:
  148. return AR6004_HOST_INTEREST_ADDRESS + item_offset;
  149. case TARGET_TYPE_AR6006:
  150. return AR6006_HOST_INTEREST_ADDRESS + item_offset;
  151. case TARGET_TYPE_AR9888:
  152. return AR9888_HOST_INTEREST_ADDRESS + item_offset;
  153. case TARGET_TYPE_AR6320:
  154. case TARGET_TYPE_AR6320V2:
  155. return AR6320_HOST_INTEREST_ADDRESS + item_offset;
  156. case TARGET_TYPE_ADRASTEA:
  157. /* ADRASTEA doesn't have a host interest address */
  158. ASSERT(0);
  159. return 0;
  160. case TARGET_TYPE_AR900B:
  161. return AR900B_HOST_INTEREST_ADDRESS + item_offset;
  162. case TARGET_TYPE_QCA9984:
  163. return QCA9984_HOST_INTEREST_ADDRESS + item_offset;
  164. case TARGET_TYPE_QCA9888:
  165. return QCA9888_HOST_INTEREST_ADDRESS + item_offset;
  166. case TARGET_TYPE_IPQ4019:
  167. return IPQ4019_HOST_INTEREST_ADDRESS + item_offset;
  168. default:
  169. ASSERT(0);
  170. return 0;
  171. }
  172. }
  173. /**
  174. * hif_max_num_receives_reached() - check max receive is reached
  175. * @scn: HIF Context
  176. * @count: unsigned int.
  177. *
  178. * Output check status as bool
  179. *
  180. * Return: bool
  181. */
  182. bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
  183. {
  184. if (QDF_IS_EPPING_ENABLED(hif_get_conparam(scn)))
  185. return count > 120;
  186. else
  187. return count > MAX_NUM_OF_RECEIVES;
  188. }
  189. /**
  190. * init_buffer_count() - initial buffer count
  191. * @maxSize: qdf_size_t
  192. *
  193. * routine to modify the initial buffer count to be allocated on an os
  194. * platform basis. Platform owner will need to modify this as needed
  195. *
  196. * Return: qdf_size_t
  197. */
  198. qdf_size_t init_buffer_count(qdf_size_t maxSize)
  199. {
  200. return maxSize;
  201. }
  202. /**
  203. * hif_save_htc_htt_config_endpoint() - save htt_tx_endpoint
  204. * @hif_ctx: hif context
  205. * @htc_htt_tx_endpoint: htt_tx_endpoint
  206. *
  207. * Return: void
  208. */
  209. void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
  210. int htc_htt_tx_endpoint)
  211. {
  212. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  213. if (!scn) {
  214. HIF_ERROR("%s: error: scn or scn->hif_sc is NULL!",
  215. __func__);
  216. return;
  217. }
  218. scn->htc_htt_tx_endpoint = htc_htt_tx_endpoint;
  219. }
  220. qdf_export_symbol(hif_save_htc_htt_config_endpoint);
  221. static const struct qwlan_hw qwlan_hw_list[] = {
  222. {
  223. .id = AR6320_REV1_VERSION,
  224. .subid = 0,
  225. .name = "QCA6174_REV1",
  226. },
  227. {
  228. .id = AR6320_REV1_1_VERSION,
  229. .subid = 0x1,
  230. .name = "QCA6174_REV1_1",
  231. },
  232. {
  233. .id = AR6320_REV1_3_VERSION,
  234. .subid = 0x2,
  235. .name = "QCA6174_REV1_3",
  236. },
  237. {
  238. .id = AR6320_REV2_1_VERSION,
  239. .subid = 0x4,
  240. .name = "QCA6174_REV2_1",
  241. },
  242. {
  243. .id = AR6320_REV2_1_VERSION,
  244. .subid = 0x5,
  245. .name = "QCA6174_REV2_2",
  246. },
  247. {
  248. .id = AR6320_REV3_VERSION,
  249. .subid = 0x6,
  250. .name = "QCA6174_REV2.3",
  251. },
  252. {
  253. .id = AR6320_REV3_VERSION,
  254. .subid = 0x8,
  255. .name = "QCA6174_REV3",
  256. },
  257. {
  258. .id = AR6320_REV3_VERSION,
  259. .subid = 0x9,
  260. .name = "QCA6174_REV3_1",
  261. },
  262. {
  263. .id = AR6320_REV3_2_VERSION,
  264. .subid = 0xA,
  265. .name = "AR6320_REV3_2_VERSION",
  266. },
  267. {
  268. .id = WCN3990_v1,
  269. .subid = 0x0,
  270. .name = "WCN3990_V1",
  271. },
  272. {
  273. .id = WCN3990_v2,
  274. .subid = 0x0,
  275. .name = "WCN3990_V2",
  276. },
  277. {
  278. .id = WCN3990_v2_1,
  279. .subid = 0x0,
  280. .name = "WCN3990_V2.1",
  281. },
  282. {
  283. .id = WCN3998,
  284. .subid = 0x0,
  285. .name = "WCN3998",
  286. },
  287. {
  288. .id = QCA9379_REV1_VERSION,
  289. .subid = 0xC,
  290. .name = "QCA9379_REV1",
  291. },
  292. {
  293. .id = QCA9379_REV1_VERSION,
  294. .subid = 0xD,
  295. .name = "QCA9379_REV1_1",
  296. }
  297. };
  298. /**
  299. * hif_get_hw_name(): get a human readable name for the hardware
  300. * @info: Target Info
  301. *
  302. * Return: human readable name for the underlying wifi hardware.
  303. */
  304. static const char *hif_get_hw_name(struct hif_target_info *info)
  305. {
  306. int i;
  307. if (info->hw_name)
  308. return info->hw_name;
  309. for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
  310. if (info->target_version == qwlan_hw_list[i].id &&
  311. info->target_revision == qwlan_hw_list[i].subid) {
  312. return qwlan_hw_list[i].name;
  313. }
  314. }
  315. info->hw_name = qdf_mem_malloc(64);
  316. if (!info->hw_name)
  317. return "Unknown Device (nomem)";
  318. i = qdf_snprint(info->hw_name, 64, "HW_VERSION=%x.",
  319. info->target_version);
  320. if (i < 0)
  321. return "Unknown Device (snprintf failure)";
  322. else
  323. return info->hw_name;
  324. }
  325. /**
  326. * hif_get_hw_info(): hif_get_hw_info
  327. * @scn: scn
  328. * @version: version
  329. * @revision: revision
  330. *
  331. * Return: n/a
  332. */
  333. void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
  334. const char **target_name)
  335. {
  336. struct hif_target_info *info = hif_get_target_info_handle(scn);
  337. struct hif_softc *sc = HIF_GET_SOFTC(scn);
  338. if (sc->bus_type == QDF_BUS_TYPE_USB)
  339. hif_usb_get_hw_info(sc);
  340. *version = info->target_version;
  341. *revision = info->target_revision;
  342. *target_name = hif_get_hw_name(info);
  343. }
  344. /**
  345. * hif_get_dev_ba(): API to get device base address.
  346. * @scn: scn
  347. * @version: version
  348. * @revision: revision
  349. *
  350. * Return: n/a
  351. */
  352. void *hif_get_dev_ba(struct hif_opaque_softc *hif_handle)
  353. {
  354. struct hif_softc *scn = (struct hif_softc *)hif_handle;
  355. return scn->mem;
  356. }
  357. qdf_export_symbol(hif_get_dev_ba);
  358. /**
  359. * hif_open(): hif_open
  360. * @qdf_ctx: QDF Context
  361. * @mode: Driver Mode
  362. * @bus_type: Bus Type
  363. * @cbk: CDS Callbacks
  364. *
  365. * API to open HIF Context
  366. *
  367. * Return: HIF Opaque Pointer
  368. */
  369. struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode,
  370. enum qdf_bus_type bus_type,
  371. struct hif_driver_state_callbacks *cbk)
  372. {
  373. struct hif_softc *scn;
  374. QDF_STATUS status = QDF_STATUS_SUCCESS;
  375. int bus_context_size = hif_bus_get_context_size(bus_type);
  376. if (bus_context_size == 0) {
  377. HIF_ERROR("%s: context size 0 not allowed", __func__);
  378. return NULL;
  379. }
  380. scn = (struct hif_softc *)qdf_mem_malloc(bus_context_size);
  381. if (!scn) {
  382. HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
  383. __func__, bus_context_size);
  384. return GET_HIF_OPAQUE_HDL(scn);
  385. }
  386. scn->qdf_dev = qdf_ctx;
  387. scn->hif_con_param = mode;
  388. qdf_atomic_init(&scn->active_tasklet_cnt);
  389. qdf_atomic_init(&scn->active_grp_tasklet_cnt);
  390. qdf_atomic_init(&scn->link_suspended);
  391. qdf_atomic_init(&scn->tasklet_from_intr);
  392. qdf_mem_copy(&scn->callbacks, cbk,
  393. sizeof(struct hif_driver_state_callbacks));
  394. scn->bus_type = bus_type;
  395. status = hif_bus_open(scn, bus_type);
  396. if (status != QDF_STATUS_SUCCESS) {
  397. HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
  398. __func__, status, bus_type);
  399. qdf_mem_free(scn);
  400. scn = NULL;
  401. }
  402. return GET_HIF_OPAQUE_HDL(scn);
  403. }
  404. #ifdef ADRASTEA_RRI_ON_DDR
  405. /**
  406. * hif_uninit_rri_on_ddr(): free consistent memory allocated for rri
  407. * @scn: hif context
  408. *
  409. * Return: none
  410. */
  411. void hif_uninit_rri_on_ddr(struct hif_softc *scn)
  412. {
  413. if (scn->vaddr_rri_on_ddr)
  414. qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
  415. (CE_COUNT * sizeof(uint32_t)),
  416. scn->vaddr_rri_on_ddr,
  417. scn->paddr_rri_on_ddr, 0);
  418. scn->vaddr_rri_on_ddr = NULL;
  419. }
  420. #endif
  421. /**
  422. * hif_close(): hif_close
  423. * @hif_ctx: hif_ctx
  424. *
  425. * Return: n/a
  426. */
  427. void hif_close(struct hif_opaque_softc *hif_ctx)
  428. {
  429. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  430. if (scn == NULL) {
  431. HIF_ERROR("%s: hif_opaque_softc is NULL", __func__);
  432. return;
  433. }
  434. if (scn->athdiag_procfs_inited) {
  435. athdiag_procfs_remove();
  436. scn->athdiag_procfs_inited = false;
  437. }
  438. if (scn->target_info.hw_name) {
  439. char *hw_name = scn->target_info.hw_name;
  440. scn->target_info.hw_name = "ErrUnloading";
  441. qdf_mem_free(hw_name);
  442. }
  443. hif_uninit_rri_on_ddr(scn);
  444. hif_bus_close(scn);
  445. qdf_mem_free(scn);
  446. }
  447. #if defined(QCA_WIFI_QCA8074) || \
  448. defined(QCA_WIFI_QCA6290) || defined(QCA_WIFI_QCA6390)
  449. static QDF_STATUS hif_hal_attach(struct hif_softc *scn)
  450. {
  451. if (ce_srng_based(scn)) {
  452. scn->hal_soc = hal_attach(scn, scn->qdf_dev);
  453. if (scn->hal_soc == NULL)
  454. return QDF_STATUS_E_FAILURE;
  455. }
  456. return QDF_STATUS_SUCCESS;
  457. }
  458. static QDF_STATUS hif_hal_detach(struct hif_softc *scn)
  459. {
  460. if (ce_srng_based(scn)) {
  461. hal_detach(scn->hal_soc);
  462. scn->hal_soc = NULL;
  463. }
  464. return QDF_STATUS_SUCCESS;
  465. }
  466. #else
  467. static QDF_STATUS hif_hal_attach(struct hif_softc *scn)
  468. {
  469. return QDF_STATUS_SUCCESS;
  470. }
  471. static QDF_STATUS hif_hal_detach(struct hif_softc *scn)
  472. {
  473. return QDF_STATUS_SUCCESS;
  474. }
  475. #endif
  476. /**
  477. * hif_enable(): hif_enable
  478. * @hif_ctx: hif_ctx
  479. * @dev: dev
  480. * @bdev: bus dev
  481. * @bid: bus ID
  482. * @bus_type: bus type
  483. * @type: enable type
  484. *
  485. * Return: QDF_STATUS
  486. */
  487. QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
  488. void *bdev,
  489. const struct hif_bus_id *bid,
  490. enum qdf_bus_type bus_type,
  491. enum hif_enable_type type)
  492. {
  493. QDF_STATUS status;
  494. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  495. if (scn == NULL) {
  496. HIF_ERROR("%s: hif_ctx = NULL", __func__);
  497. return QDF_STATUS_E_NULL_VALUE;
  498. }
  499. status = hif_enable_bus(scn, dev, bdev, bid, type);
  500. if (status != QDF_STATUS_SUCCESS) {
  501. HIF_ERROR("%s: hif_enable_bus error = %d",
  502. __func__, status);
  503. return status;
  504. }
  505. status = hif_hal_attach(scn);
  506. if (status != QDF_STATUS_SUCCESS) {
  507. HIF_ERROR("%s: hal attach failed", __func__);
  508. goto disable_bus;
  509. }
  510. if (hif_bus_configure(scn)) {
  511. HIF_ERROR("%s: Target probe failed.", __func__);
  512. status = QDF_STATUS_E_FAILURE;
  513. goto hal_detach;
  514. }
  515. hif_ut_suspend_init(scn);
  516. /*
  517. * Flag to avoid potential unallocated memory access from MSI
  518. * interrupt handler which could get scheduled as soon as MSI
  519. * is enabled, i.e to take care of the race due to the order
  520. * in where MSI is enabled before the memory, that will be
  521. * in interrupt handlers, is allocated.
  522. */
  523. scn->hif_init_done = true;
  524. HIF_DBG("%s: OK", __func__);
  525. return QDF_STATUS_SUCCESS;
  526. hal_detach:
  527. hif_hal_detach(scn);
  528. disable_bus:
  529. hif_disable_bus(scn);
  530. return status;
  531. }
  532. void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
  533. {
  534. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  535. if (!scn)
  536. return;
  537. hif_nointrs(scn);
  538. if (scn->hif_init_done == false)
  539. hif_shutdown_device(hif_ctx);
  540. else
  541. hif_stop(hif_ctx);
  542. hif_hal_detach(scn);
  543. hif_disable_bus(scn);
  544. hif_wlan_disable(scn);
  545. scn->notice_send = false;
  546. HIF_DBG("%s: X", __func__);
  547. }
  548. void hif_display_stats(struct hif_opaque_softc *hif_ctx)
  549. {
  550. hif_display_bus_stats(hif_ctx);
  551. }
  552. void hif_clear_stats(struct hif_opaque_softc *hif_ctx)
  553. {
  554. hif_clear_bus_stats(hif_ctx);
  555. }
  556. /**
  557. * hif_crash_shutdown_dump_bus_register() - dump bus registers
  558. * @hif_ctx: hif_ctx
  559. *
  560. * Return: n/a
  561. */
  562. #if defined(TARGET_RAMDUMP_AFTER_KERNEL_PANIC) \
  563. && defined(DEBUG)
  564. static void hif_crash_shutdown_dump_bus_register(void *hif_ctx)
  565. {
  566. struct hif_opaque_softc *scn = hif_ctx;
  567. if (hif_check_soc_status(scn))
  568. return;
  569. if (hif_dump_registers(scn))
  570. HIF_ERROR("Failed to dump bus registers!");
  571. }
  572. /**
  573. * hif_crash_shutdown(): hif_crash_shutdown
  574. *
  575. * This function is called by the platform driver to dump CE registers
  576. *
  577. * @hif_ctx: hif_ctx
  578. *
  579. * Return: n/a
  580. */
  581. void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
  582. {
  583. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  584. if (!hif_ctx)
  585. return;
  586. if (scn->bus_type == QDF_BUS_TYPE_SNOC) {
  587. HIF_INFO_MED("%s: RAM dump disabled for bustype %d",
  588. __func__, scn->bus_type);
  589. return;
  590. }
  591. if (TARGET_STATUS_RESET == scn->target_status) {
  592. HIF_INFO_MED("%s: Target is already asserted, ignore!",
  593. __func__);
  594. return;
  595. }
  596. if (hif_is_load_or_unload_in_progress(scn)) {
  597. HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
  598. return;
  599. }
  600. hif_crash_shutdown_dump_bus_register(hif_ctx);
  601. if (ol_copy_ramdump(hif_ctx))
  602. goto out;
  603. HIF_INFO_MED("%s: RAM dump collecting completed!", __func__);
  604. out:
  605. return;
  606. }
  607. #else
  608. void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
  609. {
  610. HIF_INFO_MED("%s: Collecting target RAM dump disabled",
  611. __func__);
  612. }
  613. #endif /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
  614. #ifdef QCA_WIFI_3_0
  615. /**
  616. * hif_check_fw_reg(): hif_check_fw_reg
  617. * @scn: scn
  618. * @state:
  619. *
  620. * Return: int
  621. */
  622. int hif_check_fw_reg(struct hif_opaque_softc *scn)
  623. {
  624. return 0;
  625. }
  626. #endif
  627. /**
  628. * hif_read_phy_mem_base(): hif_read_phy_mem_base
  629. * @scn: scn
  630. * @phy_mem_base: physical mem base
  631. *
  632. * Return: n/a
  633. */
  634. void hif_read_phy_mem_base(struct hif_softc *scn, qdf_dma_addr_t *phy_mem_base)
  635. {
  636. *phy_mem_base = scn->mem_pa;
  637. }
  638. qdf_export_symbol(hif_read_phy_mem_base);
  639. /**
  640. * hif_get_device_type(): hif_get_device_type
  641. * @device_id: device_id
  642. * @revision_id: revision_id
  643. * @hif_type: returned hif_type
  644. * @target_type: returned target_type
  645. *
  646. * Return: int
  647. */
  648. int hif_get_device_type(uint32_t device_id,
  649. uint32_t revision_id,
  650. uint32_t *hif_type, uint32_t *target_type)
  651. {
  652. int ret = 0;
  653. switch (device_id) {
  654. case ADRASTEA_DEVICE_ID_P2_E12:
  655. *hif_type = HIF_TYPE_ADRASTEA;
  656. *target_type = TARGET_TYPE_ADRASTEA;
  657. break;
  658. case AR9888_DEVICE_ID:
  659. *hif_type = HIF_TYPE_AR9888;
  660. *target_type = TARGET_TYPE_AR9888;
  661. break;
  662. case AR6320_DEVICE_ID:
  663. switch (revision_id) {
  664. case AR6320_FW_1_1:
  665. case AR6320_FW_1_3:
  666. *hif_type = HIF_TYPE_AR6320;
  667. *target_type = TARGET_TYPE_AR6320;
  668. break;
  669. case AR6320_FW_2_0:
  670. case AR6320_FW_3_0:
  671. case AR6320_FW_3_2:
  672. *hif_type = HIF_TYPE_AR6320V2;
  673. *target_type = TARGET_TYPE_AR6320V2;
  674. break;
  675. default:
  676. HIF_ERROR("%s: error - dev_id = 0x%x, rev_id = 0x%x",
  677. __func__, device_id, revision_id);
  678. ret = -ENODEV;
  679. goto end;
  680. }
  681. break;
  682. case AR9887_DEVICE_ID:
  683. *hif_type = HIF_TYPE_AR9888;
  684. *target_type = TARGET_TYPE_AR9888;
  685. HIF_INFO(" *********** AR9887 **************");
  686. break;
  687. case QCA9984_DEVICE_ID:
  688. *hif_type = HIF_TYPE_QCA9984;
  689. *target_type = TARGET_TYPE_QCA9984;
  690. HIF_INFO(" *********** QCA9984 *************");
  691. break;
  692. case QCA9888_DEVICE_ID:
  693. *hif_type = HIF_TYPE_QCA9888;
  694. *target_type = TARGET_TYPE_QCA9888;
  695. HIF_INFO(" *********** QCA9888 *************");
  696. break;
  697. case AR900B_DEVICE_ID:
  698. *hif_type = HIF_TYPE_AR900B;
  699. *target_type = TARGET_TYPE_AR900B;
  700. HIF_INFO(" *********** AR900B *************");
  701. break;
  702. case IPQ4019_DEVICE_ID:
  703. *hif_type = HIF_TYPE_IPQ4019;
  704. *target_type = TARGET_TYPE_IPQ4019;
  705. HIF_INFO(" *********** IPQ4019 *************");
  706. break;
  707. case QCA8074_DEVICE_ID:
  708. *hif_type = HIF_TYPE_QCA8074;
  709. *target_type = TARGET_TYPE_QCA8074;
  710. HIF_INFO(" *********** QCA8074 *************\n");
  711. break;
  712. case QCA6290_EMULATION_DEVICE_ID:
  713. case QCA6290_DEVICE_ID:
  714. *hif_type = HIF_TYPE_QCA6290;
  715. *target_type = TARGET_TYPE_QCA6290;
  716. HIF_INFO(" *********** QCA6290EMU *************\n");
  717. break;
  718. case QCN7605_COMPOSITE:
  719. case QCN7605_STANDALONE:
  720. *hif_type = HIF_TYPE_QCN7605;
  721. *target_type = TARGET_TYPE_QCN7605;
  722. HIF_INFO(" *********** QCN7605 *************\n");
  723. break;
  724. case QCA6390_DEVICE_ID:
  725. case QCA6390_EMULATION_DEVICE_ID:
  726. *hif_type = HIF_TYPE_QCA6390;
  727. *target_type = TARGET_TYPE_QCA6390;
  728. HIF_INFO(" *********** QCA6390 *************\n");
  729. break;
  730. case QCA8074V2_DEVICE_ID:
  731. case RUMIM2M_DEVICE_ID_NODE0:
  732. case RUMIM2M_DEVICE_ID_NODE1:
  733. case RUMIM2M_DEVICE_ID_NODE2:
  734. case RUMIM2M_DEVICE_ID_NODE3:
  735. *hif_type = HIF_TYPE_QCA8074V2;
  736. *target_type = TARGET_TYPE_QCA8074V2;
  737. HIF_INFO(" *********** QCA8074V2 *************\n");
  738. break;
  739. default:
  740. HIF_ERROR("%s: Unsupported device ID = 0x%x!",
  741. __func__, device_id);
  742. ret = -ENODEV;
  743. break;
  744. }
  745. if (*target_type == TARGET_TYPE_UNKNOWN) {
  746. HIF_ERROR("%s: Unsupported target_type!", __func__);
  747. ret = -ENODEV;
  748. }
  749. end:
  750. return ret;
  751. }
  752. /**
  753. * hif_get_bus_type() - return the bus type
  754. *
  755. * Return: enum qdf_bus_type
  756. */
  757. enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl)
  758. {
  759. struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
  760. return scn->bus_type;
  761. }
  762. /**
  763. * Target info and ini parameters are global to the driver
  764. * Hence these structures are exposed to all the modules in
  765. * the driver and they don't need to maintains multiple copies
  766. * of the same info, instead get the handle from hif and
  767. * modify them in hif
  768. */
  769. /**
  770. * hif_get_ini_handle() - API to get hif_config_param handle
  771. * @hif_ctx: HIF Context
  772. *
  773. * Return: pointer to hif_config_info
  774. */
  775. struct hif_config_info *hif_get_ini_handle(struct hif_opaque_softc *hif_ctx)
  776. {
  777. struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
  778. return &sc->hif_config;
  779. }
  780. /**
  781. * hif_get_target_info_handle() - API to get hif_target_info handle
  782. * @hif_ctx: HIF context
  783. *
  784. * Return: Pointer to hif_target_info
  785. */
  786. struct hif_target_info *hif_get_target_info_handle(
  787. struct hif_opaque_softc *hif_ctx)
  788. {
  789. struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
  790. return &sc->target_info;
  791. }
  792. qdf_export_symbol(hif_get_target_info_handle);
  793. #ifdef RECEIVE_OFFLOAD
  794. void hif_offld_flush_cb_register(struct hif_opaque_softc *scn,
  795. void (offld_flush_handler)(void *))
  796. {
  797. if (hif_napi_enabled(scn, -1))
  798. hif_napi_rx_offld_flush_cb_register(scn, offld_flush_handler);
  799. else
  800. HIF_ERROR("NAPI not enabled\n");
  801. }
  802. qdf_export_symbol(hif_offld_flush_cb_register);
  803. void hif_offld_flush_cb_deregister(struct hif_opaque_softc *scn)
  804. {
  805. if (hif_napi_enabled(scn, -1))
  806. hif_napi_rx_offld_flush_cb_deregister(scn);
  807. else
  808. HIF_ERROR("NAPI not enabled\n");
  809. }
  810. qdf_export_symbol(hif_offld_flush_cb_deregister);
  811. int hif_get_rx_ctx_id(int ctx_id, struct hif_opaque_softc *hif_hdl)
  812. {
  813. if (hif_napi_enabled(hif_hdl, -1))
  814. return NAPI_PIPE2ID(ctx_id);
  815. else
  816. return ctx_id;
  817. }
  818. #else /* RECEIVE_OFFLOAD */
  819. int hif_get_rx_ctx_id(int ctx_id, struct hif_opaque_softc *hif_hdl)
  820. {
  821. return 0;
  822. }
  823. #endif /* RECEIVE_OFFLOAD */
  824. #if defined(FEATURE_LRO)
  825. /**
  826. * hif_get_lro_info - Returns LRO instance for instance ID
  827. * @ctx_id: LRO instance ID
  828. * @hif_hdl: HIF Context
  829. *
  830. * Return: Pointer to LRO instance.
  831. */
  832. void *hif_get_lro_info(int ctx_id, struct hif_opaque_softc *hif_hdl)
  833. {
  834. void *data;
  835. if (hif_napi_enabled(hif_hdl, -1))
  836. data = hif_napi_get_lro_info(hif_hdl, ctx_id);
  837. else
  838. data = hif_ce_get_lro_ctx(hif_hdl, ctx_id);
  839. return data;
  840. }
  841. #endif
  842. /**
  843. * hif_get_target_status - API to get target status
  844. * @hif_ctx: HIF Context
  845. *
  846. * Return: enum hif_target_status
  847. */
  848. enum hif_target_status hif_get_target_status(struct hif_opaque_softc *hif_ctx)
  849. {
  850. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  851. return scn->target_status;
  852. }
  853. qdf_export_symbol(hif_get_target_status);
  854. /**
  855. * hif_set_target_status() - API to set target status
  856. * @hif_ctx: HIF Context
  857. * @status: Target Status
  858. *
  859. * Return: void
  860. */
  861. void hif_set_target_status(struct hif_opaque_softc *hif_ctx, enum
  862. hif_target_status status)
  863. {
  864. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  865. scn->target_status = status;
  866. }
  867. /**
  868. * hif_init_ini_config() - API to initialize HIF configuration parameters
  869. * @hif_ctx: HIF Context
  870. * @cfg: HIF Configuration
  871. *
  872. * Return: void
  873. */
  874. void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
  875. struct hif_config_info *cfg)
  876. {
  877. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  878. qdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
  879. }
  880. /**
  881. * hif_get_conparam() - API to get driver mode in HIF
  882. * @scn: HIF Context
  883. *
  884. * Return: driver mode of operation
  885. */
  886. uint32_t hif_get_conparam(struct hif_softc *scn)
  887. {
  888. if (!scn)
  889. return 0;
  890. return scn->hif_con_param;
  891. }
  892. /**
  893. * hif_get_callbacks_handle() - API to get callbacks Handle
  894. * @scn: HIF Context
  895. *
  896. * Return: pointer to HIF Callbacks
  897. */
  898. struct hif_driver_state_callbacks *hif_get_callbacks_handle(
  899. struct hif_softc *scn)
  900. {
  901. return &scn->callbacks;
  902. }
  903. /**
  904. * hif_is_driver_unloading() - API to query upper layers if driver is unloading
  905. * @scn: HIF Context
  906. *
  907. * Return: True/False
  908. */
  909. bool hif_is_driver_unloading(struct hif_softc *scn)
  910. {
  911. struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
  912. if (cbk && cbk->is_driver_unloading)
  913. return cbk->is_driver_unloading(cbk->context);
  914. return false;
  915. }
  916. /**
  917. * hif_is_load_or_unload_in_progress() - API to query upper layers if
  918. * load/unload in progress
  919. * @scn: HIF Context
  920. *
  921. * Return: True/False
  922. */
  923. bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
  924. {
  925. struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
  926. if (cbk && cbk->is_load_unload_in_progress)
  927. return cbk->is_load_unload_in_progress(cbk->context);
  928. return false;
  929. }
  930. /**
  931. * hif_is_recovery_in_progress() - API to query upper layers if recovery in
  932. * progress
  933. * @scn: HIF Context
  934. *
  935. * Return: True/False
  936. */
  937. bool hif_is_recovery_in_progress(struct hif_softc *scn)
  938. {
  939. struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
  940. if (cbk && cbk->is_recovery_in_progress)
  941. return cbk->is_recovery_in_progress(cbk->context);
  942. return false;
  943. }
  944. #if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB)
  945. /**
  946. * hif_update_pipe_callback() - API to register pipe specific callbacks
  947. * @osc: Opaque softc
  948. * @pipeid: pipe id
  949. * @callbacks: callbacks to register
  950. *
  951. * Return: void
  952. */
  953. void hif_update_pipe_callback(struct hif_opaque_softc *osc,
  954. u_int8_t pipeid,
  955. struct hif_msg_callbacks *callbacks)
  956. {
  957. struct hif_softc *scn = HIF_GET_SOFTC(osc);
  958. struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
  959. struct HIF_CE_pipe_info *pipe_info;
  960. QDF_BUG(pipeid < CE_COUNT_MAX);
  961. HIF_INFO_LO("+%s pipeid %d\n", __func__, pipeid);
  962. pipe_info = &hif_state->pipe_info[pipeid];
  963. qdf_mem_copy(&pipe_info->pipe_callbacks,
  964. callbacks, sizeof(pipe_info->pipe_callbacks));
  965. HIF_INFO_LO("-%s\n", __func__);
  966. }
  967. qdf_export_symbol(hif_update_pipe_callback);
  968. /**
  969. * hif_is_target_ready() - API to query if target is in ready state
  970. * progress
  971. * @scn: HIF Context
  972. *
  973. * Return: True/False
  974. */
  975. bool hif_is_target_ready(struct hif_softc *scn)
  976. {
  977. struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
  978. if (cbk && cbk->is_target_ready)
  979. return cbk->is_target_ready(cbk->context);
  980. return false;
  981. }
  982. /**
  983. * hif_batch_send() - API to access hif specific function
  984. * ce_batch_send.
  985. * @osc: HIF Context
  986. * @msdu : list of msdus to be sent
  987. * @transfer_id : transfer id
  988. * @len : donwloaded length
  989. *
  990. * Return: list of msds not sent
  991. */
  992. qdf_nbuf_t hif_batch_send(struct hif_opaque_softc *osc, qdf_nbuf_t msdu,
  993. uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
  994. {
  995. void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
  996. return ce_batch_send((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
  997. len, sendhead);
  998. }
  999. qdf_export_symbol(hif_batch_send);
  1000. /**
  1001. * hif_update_tx_ring() - API to access hif specific function
  1002. * ce_update_tx_ring.
  1003. * @osc: HIF Context
  1004. * @num_htt_cmpls : number of htt compl received.
  1005. *
  1006. * Return: void
  1007. */
  1008. void hif_update_tx_ring(struct hif_opaque_softc *osc, u_int32_t num_htt_cmpls)
  1009. {
  1010. void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
  1011. ce_update_tx_ring(ce_tx_hdl, num_htt_cmpls);
  1012. }
  1013. qdf_export_symbol(hif_update_tx_ring);
  1014. /**
  1015. * hif_send_single() - API to access hif specific function
  1016. * ce_send_single.
  1017. * @osc: HIF Context
  1018. * @msdu : msdu to be sent
  1019. * @transfer_id: transfer id
  1020. * @len : downloaded length
  1021. *
  1022. * Return: msdu sent status
  1023. */
  1024. int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
  1025. transfer_id, u_int32_t len)
  1026. {
  1027. void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
  1028. return ce_send_single((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
  1029. len);
  1030. }
  1031. qdf_export_symbol(hif_send_single);
  1032. #ifdef WLAN_FEATURE_FASTPATH
  1033. /**
  1034. * hif_send_fast() - API to access hif specific function
  1035. * ce_send_fast.
  1036. * @osc: HIF Context
  1037. * @msdu : array of msdus to be sent
  1038. * @num_msdus : number of msdus in an array
  1039. * @transfer_id: transfer id
  1040. * @download_len: download length
  1041. *
  1042. * Return: No. of packets that could be sent
  1043. */
  1044. int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t nbuf,
  1045. uint32_t transfer_id, uint32_t download_len)
  1046. {
  1047. void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
  1048. return ce_send_fast((struct CE_handle *)ce_tx_hdl, nbuf,
  1049. transfer_id, download_len);
  1050. }
  1051. qdf_export_symbol(hif_send_fast);
  1052. #endif
  1053. #endif
  1054. /**
  1055. * hif_reg_write() - API to access hif specific function
  1056. * hif_write32_mb.
  1057. * @hif_ctx : HIF Context
  1058. * @offset : offset on which value has to be written
  1059. * @value : value to be written
  1060. *
  1061. * Return: None
  1062. */
  1063. void hif_reg_write(struct hif_opaque_softc *hif_ctx, uint32_t offset,
  1064. uint32_t value)
  1065. {
  1066. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  1067. hif_write32_mb(scn, scn->mem + offset, value);
  1068. }
  1069. qdf_export_symbol(hif_reg_write);
  1070. /**
  1071. * hif_reg_read() - API to access hif specific function
  1072. * hif_read32_mb.
  1073. * @hif_ctx : HIF Context
  1074. * @offset : offset from which value has to be read
  1075. *
  1076. * Return: Read value
  1077. */
  1078. uint32_t hif_reg_read(struct hif_opaque_softc *hif_ctx, uint32_t offset)
  1079. {
  1080. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  1081. return hif_read32_mb(scn, scn->mem + offset);
  1082. }
  1083. qdf_export_symbol(hif_reg_read);
  1084. /**
  1085. * hif_ramdump_handler(): generic ramdump handler
  1086. * @scn: struct hif_opaque_softc
  1087. *
  1088. * Return: None
  1089. */
  1090. void hif_ramdump_handler(struct hif_opaque_softc *scn)
  1091. {
  1092. if (hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
  1093. hif_usb_ramdump_handler(scn);
  1094. }
  1095. #ifdef WLAN_SUSPEND_RESUME_TEST
  1096. irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
  1097. {
  1098. struct hif_softc *scn = context;
  1099. HIF_INFO("wake interrupt received on irq %d", irq);
  1100. if (scn->initial_wakeup_cb)
  1101. scn->initial_wakeup_cb(scn->initial_wakeup_priv);
  1102. if (hif_is_ut_suspended(scn))
  1103. hif_ut_fw_resume(scn);
  1104. return IRQ_HANDLED;
  1105. }
  1106. #else /* WLAN_SUSPEND_RESUME_TEST */
  1107. irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
  1108. {
  1109. struct hif_softc *scn = context;
  1110. HIF_INFO("wake interrupt received on irq %d", irq);
  1111. if (scn->initial_wakeup_cb)
  1112. scn->initial_wakeup_cb(scn->initial_wakeup_priv);
  1113. return IRQ_HANDLED;
  1114. }
  1115. #endif /* WLAN_SUSPEND_RESUME_TEST */
  1116. void hif_set_initial_wakeup_cb(struct hif_opaque_softc *hif_ctx,
  1117. void (*callback)(void *),
  1118. void *priv)
  1119. {
  1120. struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
  1121. scn->initial_wakeup_cb = callback;
  1122. scn->initial_wakeup_priv = priv;
  1123. }
  1124. void hif_set_ce_service_max_yield_time(struct hif_opaque_softc *hif,
  1125. uint32_t ce_service_max_yield_time)
  1126. {
  1127. struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif);
  1128. hif_ctx->ce_service_max_yield_time =
  1129. ce_service_max_yield_time * 1000;
  1130. }
  1131. unsigned long long
  1132. hif_get_ce_service_max_yield_time(struct hif_opaque_softc *hif)
  1133. {
  1134. struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif);
  1135. return hif_ctx->ce_service_max_yield_time;
  1136. }
  1137. void hif_set_ce_service_max_rx_ind_flush(struct hif_opaque_softc *hif,
  1138. uint8_t ce_service_max_rx_ind_flush)
  1139. {
  1140. struct hif_softc *hif_ctx = HIF_GET_SOFTC(hif);
  1141. if (ce_service_max_rx_ind_flush == 0 ||
  1142. ce_service_max_rx_ind_flush > MSG_FLUSH_NUM)
  1143. hif_ctx->ce_service_max_rx_ind_flush = MSG_FLUSH_NUM;
  1144. else
  1145. hif_ctx->ce_service_max_rx_ind_flush =
  1146. ce_service_max_rx_ind_flush;
  1147. }