blob: 9df3bd510334f266692838eaef346ec2cda2eff4 [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Houston Hoffmancceec342015-11-11 11:37:20 -08002 * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080028#include "targcfg.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053029#include "qdf_lock.h"
30#include "qdf_status.h"
31#include "qdf_status.h"
32#include <qdf_atomic.h> /* qdf_atomic_read */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080033#include <targaddrs.h>
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080034#include "hif_io32.h"
35#include <hif.h>
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080036#include "regtable.h"
37#define ATH_MODULE_NAME hif
38#include <a_debug.h>
39#include "hif_main.h"
40#include "hif_hw_version.h"
41#include "ce_api.h"
42#include "ce_tasklet.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053043#include "qdf_trace.h"
44#include "qdf_status.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080045#ifdef CONFIG_CNSS
46#include <net/cnss.h>
47#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080048#include "hif_debug.h"
49#include "mp_dev.h"
Houston Hoffmanbc693492016-03-14 21:11:41 -070050#include "platform_icnss.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080051
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080052#define AGC_DUMP 1
53#define CHANINFO_DUMP 2
54#define BB_WATCHDOG_DUMP 3
55#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
56#define PCIE_ACCESS_DUMP 4
57#endif
58
Komal Seelam5584a7c2016-02-24 19:22:48 +053059void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080060{
Komal Seelam644263d2016-02-22 20:45:49 +053061 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080062 switch (cmd_id) {
63 case AGC_DUMP:
64 if (start)
65 priv_start_agc(scn);
66 else
67 priv_dump_agc(scn);
68 break;
69
70 case CHANINFO_DUMP:
71 if (start)
72 priv_start_cap_chaninfo(scn);
73 else
74 priv_dump_chaninfo(scn);
75 break;
76
77 case BB_WATCHDOG_DUMP:
78 priv_dump_bbwatchdog(scn);
79 break;
80
81#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
82 case PCIE_ACCESS_DUMP:
83 hif_target_dump_access_log();
84 break;
85#endif
86 default:
87 HIF_ERROR("%s: Invalid htc dump command", __func__);
88 break;
89 }
90}
91
92/**
93 * hif_shut_down_device() - hif_shut_down_device
94 *
95 * SThis fucntion shuts down the device
96 *
Komal Seelam5584a7c2016-02-24 19:22:48 +053097 * @scn: hif_opaque_softc
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080098 *
99 * Return: void
100 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530101void hif_shut_down_device(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800102{
Komal Seelam02cf2f82016-02-22 20:44:25 +0530103 hif_stop(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800104}
105
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800106/**
107 * hif_get_target_id(): hif_get_target_id
108 *
109 * Return the virtual memory base address to the caller
110 *
Komal Seelam644263d2016-02-22 20:45:49 +0530111 * @scn: hif_softc
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800112 *
113 * Return: A_target_id_t
114 */
Komal Seelam644263d2016-02-22 20:45:49 +0530115A_target_id_t hif_get_target_id(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800116{
117 return scn->mem;
118}
119
Houston Hoffman0dad5092015-09-28 16:25:51 -0700120static inline void hif_fw_event_handler(struct HIF_CE_state *hif_state)
121{
122 struct hif_msg_callbacks *msg_callbacks =
123 &hif_state->msg_callbacks_current;
124
125 if (!msg_callbacks->fwEventHandler)
126 return;
127
128 msg_callbacks->fwEventHandler(msg_callbacks->Context,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530129 QDF_STATUS_E_FAILURE);
Houston Hoffman0dad5092015-09-28 16:25:51 -0700130}
131
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800132/**
133 * hif_fw_interrupt_handler(): FW interrupt handler
134 *
135 * This function is the FW interrupt handlder
136 *
137 * @irq: irq number
138 * @arg: the user pointer
139 *
140 * Return: bool
141 */
142#ifndef QCA_WIFI_3_0
143irqreturn_t hif_fw_interrupt_handler(int irq, void *arg)
144{
Komal Seelam644263d2016-02-22 20:45:49 +0530145 struct hif_softc *scn = arg;
Komal Seelam02cf2f82016-02-22 20:44:25 +0530146 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800147 uint32_t fw_indicator_address, fw_indicator;
148
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700149 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
150 return ATH_ISR_NOSCHED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800151
152 fw_indicator_address = hif_state->fw_indicator_address;
153 /* For sudden unplug this will return ~0 */
154 fw_indicator = A_TARGET_READ(scn, fw_indicator_address);
155
156 if ((fw_indicator != ~0) && (fw_indicator & FW_IND_EVENT_PENDING)) {
157 /* ACK: clear Target-side pending event */
158 A_TARGET_WRITE(scn, fw_indicator_address,
159 fw_indicator & ~FW_IND_EVENT_PENDING);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700160 if (Q_TARGET_ACCESS_END(scn) < 0)
161 return ATH_ISR_SCHED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800162
163 if (hif_state->started) {
Houston Hoffman0dad5092015-09-28 16:25:51 -0700164 hif_fw_event_handler(hif_state);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800165 } else {
166 /*
167 * Probable Target failure before we're prepared
168 * to handle it. Generally unexpected.
169 */
170 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
171 ("%s: Early firmware event indicated\n",
172 __func__));
173 }
174 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700175 if (Q_TARGET_ACCESS_END(scn) < 0)
176 return ATH_ISR_SCHED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800177 }
178
179 return ATH_ISR_SCHED;
180}
181#else
182irqreturn_t hif_fw_interrupt_handler(int irq, void *arg)
183{
184 return ATH_ISR_SCHED;
185}
186#endif /* #ifdef QCA_WIFI_3_0 */
187
188/**
189 * hif_get_targetdef(): hif_get_targetdef
190 * @scn: scn
191 *
192 * Return: void *
193 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530194void *hif_get_targetdef(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800195{
Komal Seelam644263d2016-02-22 20:45:49 +0530196 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
197
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800198 return scn->targetdef;
199}
200
201/**
202 * hif_vote_link_down(): unvote for link up
203 *
204 * Call hif_vote_link_down to release a previous request made using
205 * hif_vote_link_up. A hif_vote_link_down call should only be made
206 * after a corresponding hif_vote_link_up, otherwise you could be
207 * negating a vote from another source. When no votes are present
208 * hif will not guarantee the linkstate after hif_bus_suspend.
209 *
210 * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
211 * and initialization deinitialization sequencences.
212 *
213 * Return: n/a
214 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530215void hif_vote_link_down(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800216{
Komal Seelam644263d2016-02-22 20:45:49 +0530217 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530218 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800219
220 scn->linkstate_vote--;
221 if (scn->linkstate_vote == 0)
Houston Hoffmancceec342015-11-11 11:37:20 -0800222 hif_bus_prevent_linkdown(scn, false);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800223}
224
225/**
226 * hif_vote_link_up(): vote to prevent bus from suspending
227 *
228 * Makes hif guarantee that fw can message the host normally
229 * durring suspend.
230 *
231 * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
232 * and initialization deinitialization sequencences.
233 *
234 * Return: n/a
235 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530236void hif_vote_link_up(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800237{
Komal Seelam644263d2016-02-22 20:45:49 +0530238 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530239 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800240
241 scn->linkstate_vote++;
242 if (scn->linkstate_vote == 1)
Houston Hoffmancceec342015-11-11 11:37:20 -0800243 hif_bus_prevent_linkdown(scn, true);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800244}
245
246/**
247 * hif_can_suspend_link(): query if hif is permitted to suspend the link
248 *
249 * Hif will ensure that the link won't be suspended if the upperlayers
250 * don't want it to.
251 *
252 * SYNCHRONIZATION: MC thread is stopped before bus suspend thus
253 * we don't need extra locking to ensure votes dont change while
254 * we are in the process of suspending or resuming.
255 *
256 * Return: false if hif will guarantee link up durring suspend.
257 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530258bool hif_can_suspend_link(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800259{
Komal Seelam644263d2016-02-22 20:45:49 +0530260 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530261 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800262
263 return scn->linkstate_vote == 0;
264}
265
266/**
267 * hif_hia_item_address(): hif_hia_item_address
268 * @target_type: target_type
269 * @item_offset: item_offset
270 *
271 * Return: n/a
272 */
273uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
274{
275 switch (target_type) {
276 case TARGET_TYPE_AR6002:
277 return AR6002_HOST_INTEREST_ADDRESS + item_offset;
278 case TARGET_TYPE_AR6003:
279 return AR6003_HOST_INTEREST_ADDRESS + item_offset;
280 case TARGET_TYPE_AR6004:
281 return AR6004_HOST_INTEREST_ADDRESS + item_offset;
282 case TARGET_TYPE_AR6006:
283 return AR6006_HOST_INTEREST_ADDRESS + item_offset;
284 case TARGET_TYPE_AR9888:
285 return AR9888_HOST_INTEREST_ADDRESS + item_offset;
286 case TARGET_TYPE_AR6320:
287 case TARGET_TYPE_AR6320V2:
288 return AR6320_HOST_INTEREST_ADDRESS + item_offset;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800289 case TARGET_TYPE_ADRASTEA:
290 /* ADRASTEA doesn't have a host interest address */
291 ASSERT(0);
292 return 0;
293 default:
294 ASSERT(0);
295 return 0;
296 }
297}
298
299/**
300 * hif_max_num_receives_reached() - check max receive is reached
Komal Seelambd7c51d2016-02-24 10:27:30 +0530301 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800302 * @count: unsigned int.
303 *
304 * Output check status as bool
305 *
306 * Return: bool
307 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530308bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800309{
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700310 if (QDF_IS_EPPING_ENABLED(hif_get_conparam(scn)))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800311 return count > 120;
312 else
313 return count > MAX_NUM_OF_RECEIVES;
314}
315
316/**
317 * init_buffer_count() - initial buffer count
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530318 * @maxSize: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800319 *
320 * routine to modify the initial buffer count to be allocated on an os
321 * platform basis. Platform owner will need to modify this as needed
322 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530323 * Return: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800324 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530325qdf_size_t init_buffer_count(qdf_size_t maxSize)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800326{
327 return maxSize;
328}
329
330/**
Nirav Shahd7f91592016-04-21 14:18:43 +0530331 * hif_save_htc_htt_config_endpoint() - save htt_tx_endpoint
332 * @hif_ctx: hif context
333 * @htc_htt_tx_endpoint: htt_tx_endpoint
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800334 *
335 * Return: void
336 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530337void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
Nirav Shahd7f91592016-04-21 14:18:43 +0530338 int htc_htt_tx_endpoint)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800339{
Komal Seelam644263d2016-02-22 20:45:49 +0530340 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800341
342 if (!scn) {
343 HIF_ERROR("%s: error: scn or scn->hif_sc is NULL!",
344 __func__);
345 return;
346 }
347
Nirav Shahd7f91592016-04-21 14:18:43 +0530348 scn->htc_htt_tx_endpoint = htc_htt_tx_endpoint;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800349}
350
351/**
352 * hif_get_hw_name(): get a human readable name for the hardware
Komal Seelam91553ce2016-01-27 18:57:10 +0530353 * @info: Target Info
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800354 *
Komal Seelam91553ce2016-01-27 18:57:10 +0530355 * Return: human readable name for the underlying wifi hardware.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800356 */
Komal Seelam91553ce2016-01-27 18:57:10 +0530357static const char *hif_get_hw_name(struct hif_target_info *info)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800358{
359 int i;
Komal Seelam91553ce2016-01-27 18:57:10 +0530360
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800361 for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
Komal Seelam91553ce2016-01-27 18:57:10 +0530362 if (info->target_version == qwlan_hw_list[i].id &&
363 info->target_revision == qwlan_hw_list[i].subid) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800364 return qwlan_hw_list[i].name;
365 }
366 }
367
368 return "Unknown Device";
369}
370
371/**
372 * hif_get_hw_info(): hif_get_hw_info
373 * @scn: scn
374 * @version: version
375 * @revision: revision
376 *
377 * Return: n/a
378 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530379void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800380 const char **target_name)
381{
Komal Seelam91553ce2016-01-27 18:57:10 +0530382 struct hif_target_info *info = hif_get_target_info_handle(scn);
383 *version = info->target_version;
384 *revision = info->target_revision;
385 *target_name = hif_get_hw_name(info);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800386}
387
388/**
389 * hif_open(): hif_open
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530390 * @qdf_ctx: QDF Context
Komal Seelambd7c51d2016-02-24 10:27:30 +0530391 * @mode: Driver Mode
392 * @bus_type: Bus Type
393 * @cbk: CDS Callbacks
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800394 *
Komal Seelambd7c51d2016-02-24 10:27:30 +0530395 * API to open HIF Context
396 *
397 * Return: HIF Opaque Pointer
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800398 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530399struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode,
400 enum qdf_bus_type bus_type,
Komal Seelam75080122016-03-02 15:18:25 +0530401 struct hif_driver_state_callbacks *cbk)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800402{
Komal Seelam644263d2016-02-22 20:45:49 +0530403 struct hif_softc *scn;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530404 QDF_STATUS status = QDF_STATUS_SUCCESS;
Houston Hoffman162164c2016-03-14 21:12:10 -0700405 int bus_context_size = hif_bus_get_context_size(bus_type);
406
407 if (bus_context_size == 0) {
408 HIF_ERROR("%s: context size 0 not allowed", __func__);
409 return NULL;
410 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800411
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530412 scn = (struct hif_softc *)qdf_mem_malloc(bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530413 if (!scn) {
414 HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
415 __func__, bus_context_size);
416 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800417 }
418
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530419 qdf_mem_zero(scn, bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530420
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530421 scn->qdf_dev = qdf_ctx;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530422 scn->hif_con_param = mode;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530423 qdf_atomic_init(&scn->active_tasklet_cnt);
424 qdf_atomic_init(&scn->link_suspended);
425 qdf_atomic_init(&scn->tasklet_from_intr);
Komal Seelam75080122016-03-02 15:18:25 +0530426 qdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_driver_state_callbacks));
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800427
428 status = hif_bus_open(scn, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530429 if (status != QDF_STATUS_SUCCESS) {
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800430 HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
431 __func__, status, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530432 qdf_mem_free(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530433 scn = NULL;
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800434 }
435
Komal Seelambd7c51d2016-02-24 10:27:30 +0530436 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800437}
438
439/**
440 * hif_close(): hif_close
441 * @hif_ctx: hif_ctx
442 *
443 * Return: n/a
444 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530445void hif_close(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800446{
Komal Seelam644263d2016-02-22 20:45:49 +0530447 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800448
449 if (scn == NULL) {
Komal Seelam5584a7c2016-02-24 19:22:48 +0530450 HIF_ERROR("%s: hif_opaque_softc is NULL", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800451 return;
452 }
453
454 if (scn->athdiag_procfs_inited) {
455 athdiag_procfs_remove();
456 scn->athdiag_procfs_inited = false;
457 }
458
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800459 hif_bus_close(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530460 qdf_mem_free(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800461}
462
463/**
464 * hif_enable(): hif_enable
465 * @hif_ctx: hif_ctx
466 * @dev: dev
467 * @bdev: bus dev
468 * @bid: bus ID
469 * @bus_type: bus type
470 * @type: enable type
471 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530472 * Return: QDF_STATUS
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800473 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530474QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800475 void *bdev, const hif_bus_id *bid,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530476 enum qdf_bus_type bus_type,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800477 enum hif_enable_type type)
478{
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530479 QDF_STATUS status;
Komal Seelam644263d2016-02-22 20:45:49 +0530480 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800481
482 if (scn == NULL) {
483 HIF_ERROR("%s: hif_ctx = NULL", __func__);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530484 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800485 }
486
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800487 status = hif_enable_bus(scn, dev, bdev, bid, type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530488 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800489 HIF_ERROR("%s: hif_enable_bus error = %d",
490 __func__, status);
491 return status;
492 }
493
494 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530495 hif_vote_link_up(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800496
Houston Hoffman108da402016-03-14 21:11:24 -0700497 if (hif_bus_configure(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800498 HIF_ERROR("%s: Target probe failed.", __func__);
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530499 hif_disable_bus(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530500 status = QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800501 return status;
502 }
Houston Hoffman108da402016-03-14 21:11:24 -0700503
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800504 /*
505 * Flag to avoid potential unallocated memory access from MSI
506 * interrupt handler which could get scheduled as soon as MSI
507 * is enabled, i.e to take care of the race due to the order
508 * in where MSI is enabled before the memory, that will be
509 * in interrupt handlers, is allocated.
510 */
511
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800512 scn->hif_init_done = true;
513
514 HIF_TRACE("%s: X OK", __func__);
515
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530516 return QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800517}
518
519/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800520 * hif_wlan_disable(): call the platform driver to disable wlan
Komal Seelambd7c51d2016-02-24 10:27:30 +0530521 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800522 *
523 * This function passes the con_mode to platform driver to disable
524 * wlan.
525 *
526 * Return: void
527 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530528void hif_wlan_disable(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800529{
530 enum icnss_driver_mode mode;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530531 uint32_t con_mode = hif_get_conparam(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800532
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530533 if (QDF_GLOBAL_FTM_MODE == con_mode)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800534 mode = ICNSS_FTM;
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700535 else if (QDF_IS_EPPING_ENABLED(con_mode))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800536 mode = ICNSS_EPPING;
Peng Xu7b962532015-10-02 17:17:03 -0700537 else
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800538 mode = ICNSS_MISSION;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800539
540 icnss_wlan_disable(mode);
541}
542
Komal Seelam5584a7c2016-02-24 19:22:48 +0530543void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800544{
Komal Seelam644263d2016-02-22 20:45:49 +0530545 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800546
547 if (!scn)
548 return;
549
550 hif_nointrs(scn);
551 if (scn->hif_init_done == false)
Komal Seelam644263d2016-02-22 20:45:49 +0530552 hif_shut_down_device(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800553 else
Komal Seelam644263d2016-02-22 20:45:49 +0530554 hif_stop(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800555
556 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530557 hif_vote_link_down(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800558
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530559 hif_disable_bus(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800560
Komal Seelambd7c51d2016-02-24 10:27:30 +0530561 hif_wlan_disable(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800562
563 scn->notice_send = false;
564
565 HIF_INFO("%s: X", __func__);
566}
567
568
569/**
Govind Singh2443fb32016-01-13 17:44:48 +0530570 * hif_crash_shutdown_dump_bus_register() - dump bus registers
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800571 * @hif_ctx: hif_ctx
572 *
573 * Return: n/a
574 */
575#if defined(TARGET_RAMDUMP_AFTER_KERNEL_PANIC) \
Houston Hoffmanbc693492016-03-14 21:11:41 -0700576&& defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800577
Govind Singh2443fb32016-01-13 17:44:48 +0530578static void hif_crash_shutdown_dump_bus_register(void *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800579{
Komal Seelam5584a7c2016-02-24 19:22:48 +0530580 struct hif_opaque_softc *scn = hif_ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800581
Govind Singh2443fb32016-01-13 17:44:48 +0530582 if (hif_check_soc_status(scn))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800583 return;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800584
Govind Singh2443fb32016-01-13 17:44:48 +0530585 if (hif_dump_registers(scn))
586 HIF_ERROR("Failed to dump bus registers!");
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800587}
588
589/**
590 * hif_crash_shutdown(): hif_crash_shutdown
591 *
592 * This function is called by the platform driver to dump CE registers
593 *
594 * @hif_ctx: hif_ctx
595 *
596 * Return: n/a
597 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530598void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800599{
Komal Seelam644263d2016-02-22 20:45:49 +0530600 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800601
Houston Hoffmanbc693492016-03-14 21:11:41 -0700602 if (!hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800603 return;
604
Houston Hoffmanbc693492016-03-14 21:11:41 -0700605 if (scn->bus_type == QDF_BUS_TYPE_SNOC) {
606 HIF_INFO_MED("%s: RAM dump disabled for bustype %d",
607 __func__, scn->bus_type);
608 return;
609 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800610
Komal Seelam6ee55902016-04-11 17:11:07 +0530611 if (TARGET_STATUS_RESET == scn->target_status) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800612 HIF_INFO_MED("%s: Target is already asserted, ignore!",
613 __func__);
614 return;
615 }
616
Komal Seelambd7c51d2016-02-24 10:27:30 +0530617 if (hif_is_load_or_unload_in_progress(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800618 HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
619 return;
620 }
621
Govind Singh2443fb32016-01-13 17:44:48 +0530622 hif_crash_shutdown_dump_bus_register(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800623
Komal Seelam644263d2016-02-22 20:45:49 +0530624 if (ol_copy_ramdump(hif_ctx))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800625 goto out;
626
627 HIF_INFO_MED("%s: RAM dump collecting completed!", __func__);
628
629out:
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800630 return;
631}
632#else
Komal Seelam5584a7c2016-02-24 19:22:48 +0530633void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800634{
635 HIF_INFO_MED("%s: Collecting target RAM dump disabled",
636 __func__);
637 return;
638}
639#endif /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
640
641#ifdef QCA_WIFI_3_0
642/**
643 * hif_check_fw_reg(): hif_check_fw_reg
644 * @scn: scn
645 * @state:
646 *
647 * Return: int
648 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530649int hif_check_fw_reg(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800650{
651 return 0;
652}
653#endif
654
655#ifdef IPA_OFFLOAD
656/**
657 * hif_read_phy_mem_base(): hif_read_phy_mem_base
658 * @scn: scn
659 * @phy_mem_base: physical mem base
660 *
661 * Return: n/a
662 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530663void hif_read_phy_mem_base(struct hif_softc *scn, qdf_dma_addr_t *phy_mem_base)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800664{
665 *phy_mem_base = scn->mem_pa;
666}
667#endif /* IPA_OFFLOAD */
668
669/**
670 * hif_get_device_type(): hif_get_device_type
671 * @device_id: device_id
672 * @revision_id: revision_id
673 * @hif_type: returned hif_type
674 * @target_type: returned target_type
675 *
676 * Return: int
677 */
678int hif_get_device_type(uint32_t device_id,
679 uint32_t revision_id,
680 uint32_t *hif_type, uint32_t *target_type)
681{
682 int ret = 0;
683
684 switch (device_id) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800685 case ADRASTEA_DEVICE_ID:
686 case ADRASTEA_DEVICE_ID_P2_E12:
687
688 *hif_type = HIF_TYPE_ADRASTEA;
689 *target_type = TARGET_TYPE_ADRASTEA;
690 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800691
692 case AR9888_DEVICE_ID:
693 *hif_type = HIF_TYPE_AR9888;
694 *target_type = TARGET_TYPE_AR9888;
695 break;
696
697 case AR6320_DEVICE_ID:
698 switch (revision_id) {
699 case AR6320_FW_1_1:
700 case AR6320_FW_1_3:
701 *hif_type = HIF_TYPE_AR6320;
702 *target_type = TARGET_TYPE_AR6320;
703 break;
704
705 case AR6320_FW_2_0:
706 case AR6320_FW_3_0:
707 case AR6320_FW_3_2:
708 *hif_type = HIF_TYPE_AR6320V2;
709 *target_type = TARGET_TYPE_AR6320V2;
710 break;
711
712 default:
713 HIF_ERROR("%s: error - dev_id = 0x%x, rev_id = 0x%x",
714 __func__, device_id, revision_id);
715 ret = -ENODEV;
716 goto end;
717 }
718 break;
719
720 default:
721 HIF_ERROR("%s: Unsupported device ID!", __func__);
722 ret = -ENODEV;
723 break;
724 }
725end:
726 return ret;
727}
Komal Seelam91553ce2016-01-27 18:57:10 +0530728
729/**
Houston Hoffman26352592016-03-14 21:11:43 -0700730 * hif_needs_bmi() - return true if the soc needs bmi through the driver
731 * @hif_ctx: hif context
732 *
733 * Return: true if the soc needs driver bmi otherwise false
734 */
735bool hif_needs_bmi(struct hif_opaque_softc *hif_ctx)
736{
737 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx);
738 return hif_sc->bus_type != QDF_BUS_TYPE_SNOC;
739}
740
741/**
Houston Hoffman60a1eeb2016-03-14 21:11:44 -0700742 * hif_get_bus_type() - return the bus type
743 *
744 * Return: enum qdf_bus_type
745 */
746enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl)
747{
748 struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
749 return scn->bus_type;
750}
751
752/**
Komal Seelam91553ce2016-01-27 18:57:10 +0530753 * Target info and ini parameters are global to the driver
754 * Hence these structures are exposed to all the modules in
755 * the driver and they don't need to maintains multiple copies
756 * of the same info, instead get the handle from hif and
757 * modify them in hif
758 */
759
760/**
761 * hif_get_ini_handle() - API to get hif_config_param handle
Komal Seelam644263d2016-02-22 20:45:49 +0530762 * @hif_ctx: HIF Context
Komal Seelam91553ce2016-01-27 18:57:10 +0530763 *
764 * Return: pointer to hif_config_info
765 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530766struct hif_config_info *hif_get_ini_handle(struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530767{
Komal Seelam644263d2016-02-22 20:45:49 +0530768 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
769
770 return &sc->hif_config;
Komal Seelam91553ce2016-01-27 18:57:10 +0530771}
772
773/**
774 * hif_get_target_info_handle() - API to get hif_target_info handle
Komal Seelam644263d2016-02-22 20:45:49 +0530775 * @hif_ctx: HIF context
Komal Seelam91553ce2016-01-27 18:57:10 +0530776 *
777 * Return: Pointer to hif_target_info
778 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530779struct hif_target_info *hif_get_target_info_handle(
780 struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530781{
Komal Seelam644263d2016-02-22 20:45:49 +0530782 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
783
784 return &sc->target_info;
785
Komal Seelam91553ce2016-01-27 18:57:10 +0530786}
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530787
788#if defined(FEATURE_LRO)
789/**
790 * hif_lro_flush_cb_register - API to register for LRO Flush Callback
791 * @scn: HIF Context
792 * @handler: Function pointer to be called by HIF
793 * @data: Private data to be used by the module registering to HIF
794 *
795 * Return: void
796 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530797void hif_lro_flush_cb_register(struct hif_opaque_softc *scn,
798 void (handler)(void *), void *data)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530799{
800 ce_lro_flush_cb_register(scn, handler, data);
801}
802
803/**
804 * hif_lro_flush_cb_deregister - API to deregister for LRO Flush Callbacks
805 * @scn: HIF Context
806 *
807 * Return: void
808 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530809void hif_lro_flush_cb_deregister(struct hif_opaque_softc *scn)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530810{
811 ce_lro_flush_cb_deregister(scn);
812}
813#endif
Komal Seelam644263d2016-02-22 20:45:49 +0530814
815/**
816 * hif_get_target_status - API to get target status
817 * @hif_ctx: HIF Context
818 *
Komal Seelam6ee55902016-04-11 17:11:07 +0530819 * Return: enum hif_target_status
Komal Seelam644263d2016-02-22 20:45:49 +0530820 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530821enum hif_target_status hif_get_target_status(struct hif_opaque_softc *hif_ctx)
Komal Seelam644263d2016-02-22 20:45:49 +0530822{
823 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
824
825 return scn->target_status;
826}
827
828/**
Komal Seelama5911d32016-02-24 19:21:59 +0530829 * hif_set_target_status() - API to set target status
Komal Seelam644263d2016-02-22 20:45:49 +0530830 * @hif_ctx: HIF Context
831 * @status: Target Status
832 *
833 * Return: void
834 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530835void hif_set_target_status(struct hif_opaque_softc *hif_ctx, enum
836 hif_target_status status)
Komal Seelam644263d2016-02-22 20:45:49 +0530837{
838 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
839
840 scn->target_status = status;
841}
Komal Seelama5911d32016-02-24 19:21:59 +0530842
843/**
844 * hif_init_ini_config() - API to initialize HIF configuration parameters
845 * @hif_ctx: HIF Context
846 * @cfg: HIF Configuration
847 *
848 * Return: void
849 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530850void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
851 struct hif_config_info *cfg)
Komal Seelama5911d32016-02-24 19:21:59 +0530852{
853 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
854
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530855 qdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
Komal Seelama5911d32016-02-24 19:21:59 +0530856}
Komal Seelambd7c51d2016-02-24 10:27:30 +0530857
858/**
859 * hif_get_conparam() - API to get driver mode in HIF
860 * @scn: HIF Context
861 *
862 * Return: driver mode of operation
863 */
864uint32_t hif_get_conparam(struct hif_softc *scn)
865{
866 if (!scn)
867 return 0;
868
869 return scn->hif_con_param;
870}
871
872/**
873 * hif_get_callbacks_handle() - API to get callbacks Handle
874 * @scn: HIF Context
875 *
876 * Return: pointer to HIF Callbacks
877 */
Komal Seelam75080122016-03-02 15:18:25 +0530878struct hif_driver_state_callbacks *hif_get_callbacks_handle(struct hif_softc *scn)
Komal Seelambd7c51d2016-02-24 10:27:30 +0530879{
880 return &scn->callbacks;
881}
882
883/**
884 * hif_is_driver_unloading() - API to query upper layers if driver is unloading
885 * @scn: HIF Context
886 *
887 * Return: True/False
888 */
889bool hif_is_driver_unloading(struct hif_softc *scn)
890{
Komal Seelam75080122016-03-02 15:18:25 +0530891 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530892
893 if (cbk && cbk->is_driver_unloading)
894 return cbk->is_driver_unloading(cbk->context);
895
896 return false;
897}
898
899/**
900 * hif_is_load_or_unload_in_progress() - API to query upper layers if
901 * load/unload in progress
902 * @scn: HIF Context
903 *
904 * Return: True/False
905 */
906bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
907{
Komal Seelam75080122016-03-02 15:18:25 +0530908 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530909
910 if (cbk && cbk->is_load_unload_in_progress)
911 return cbk->is_load_unload_in_progress(cbk->context);
912
913 return false;
914}
915
916/**
917 * hif_is_recovery_in_progress() - API to query upper layers if recovery in
918 * progress
919 * @scn: HIF Context
920 *
921 * Return: True/False
922 */
923bool hif_is_recovery_in_progress(struct hif_softc *scn)
924{
Komal Seelam75080122016-03-02 15:18:25 +0530925 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530926
927 if (cbk && cbk->is_recovery_in_progress)
928 return cbk->is_recovery_in_progress(cbk->context);
929
930 return false;
931}