blob: 05b7c8edce8217c93119d4464b36fed546e39b39 [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>
34#include <bmi_msg.h>
35#include "hif_io32.h"
36#include <hif.h>
37#include <htc_services.h>
38#include "regtable.h"
39#define ATH_MODULE_NAME hif
40#include <a_debug.h>
41#include "hif_main.h"
42#include "hif_hw_version.h"
43#include "ce_api.h"
44#include "ce_tasklet.h"
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053045#include "qdf_trace.h"
46#include "qdf_status.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080047#ifdef CONFIG_CNSS
48#include <net/cnss.h>
49#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080050#include "epping_main.h"
51#include "hif_debug.h"
52#include "mp_dev.h"
Houston Hoffmanbc693492016-03-14 21:11:41 -070053#include "platform_icnss.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080054
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080055#define AGC_DUMP 1
56#define CHANINFO_DUMP 2
57#define BB_WATCHDOG_DUMP 3
58#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
59#define PCIE_ACCESS_DUMP 4
60#endif
61
Komal Seelam5584a7c2016-02-24 19:22:48 +053062void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080063{
Komal Seelam644263d2016-02-22 20:45:49 +053064 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080065 switch (cmd_id) {
66 case AGC_DUMP:
67 if (start)
68 priv_start_agc(scn);
69 else
70 priv_dump_agc(scn);
71 break;
72
73 case CHANINFO_DUMP:
74 if (start)
75 priv_start_cap_chaninfo(scn);
76 else
77 priv_dump_chaninfo(scn);
78 break;
79
80 case BB_WATCHDOG_DUMP:
81 priv_dump_bbwatchdog(scn);
82 break;
83
84#ifdef CONFIG_ATH_PCIE_ACCESS_DEBUG
85 case PCIE_ACCESS_DUMP:
86 hif_target_dump_access_log();
87 break;
88#endif
89 default:
90 HIF_ERROR("%s: Invalid htc dump command", __func__);
91 break;
92 }
93}
94
95/**
96 * hif_shut_down_device() - hif_shut_down_device
97 *
98 * SThis fucntion shuts down the device
99 *
Komal Seelam5584a7c2016-02-24 19:22:48 +0530100 * @scn: hif_opaque_softc
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800101 *
102 * Return: void
103 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530104void hif_shut_down_device(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800105{
Komal Seelam02cf2f82016-02-22 20:44:25 +0530106 hif_stop(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800107}
108
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800109/**
110 * hif_get_target_id(): hif_get_target_id
111 *
112 * Return the virtual memory base address to the caller
113 *
Komal Seelam644263d2016-02-22 20:45:49 +0530114 * @scn: hif_softc
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800115 *
116 * Return: A_target_id_t
117 */
Komal Seelam644263d2016-02-22 20:45:49 +0530118A_target_id_t hif_get_target_id(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800119{
120 return scn->mem;
121}
122
Houston Hoffman0dad5092015-09-28 16:25:51 -0700123static inline void hif_fw_event_handler(struct HIF_CE_state *hif_state)
124{
125 struct hif_msg_callbacks *msg_callbacks =
126 &hif_state->msg_callbacks_current;
127
128 if (!msg_callbacks->fwEventHandler)
129 return;
130
131 msg_callbacks->fwEventHandler(msg_callbacks->Context,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530132 QDF_STATUS_E_FAILURE);
Houston Hoffman0dad5092015-09-28 16:25:51 -0700133}
134
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800135/**
136 * hif_fw_interrupt_handler(): FW interrupt handler
137 *
138 * This function is the FW interrupt handlder
139 *
140 * @irq: irq number
141 * @arg: the user pointer
142 *
143 * Return: bool
144 */
145#ifndef QCA_WIFI_3_0
146irqreturn_t hif_fw_interrupt_handler(int irq, void *arg)
147{
Komal Seelam644263d2016-02-22 20:45:49 +0530148 struct hif_softc *scn = arg;
Komal Seelam02cf2f82016-02-22 20:44:25 +0530149 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800150 uint32_t fw_indicator_address, fw_indicator;
151
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700152 if (Q_TARGET_ACCESS_BEGIN(scn) < 0)
153 return ATH_ISR_NOSCHED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800154
155 fw_indicator_address = hif_state->fw_indicator_address;
156 /* For sudden unplug this will return ~0 */
157 fw_indicator = A_TARGET_READ(scn, fw_indicator_address);
158
159 if ((fw_indicator != ~0) && (fw_indicator & FW_IND_EVENT_PENDING)) {
160 /* ACK: clear Target-side pending event */
161 A_TARGET_WRITE(scn, fw_indicator_address,
162 fw_indicator & ~FW_IND_EVENT_PENDING);
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700163 if (Q_TARGET_ACCESS_END(scn) < 0)
164 return ATH_ISR_SCHED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800165
166 if (hif_state->started) {
Houston Hoffman0dad5092015-09-28 16:25:51 -0700167 hif_fw_event_handler(hif_state);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800168 } else {
169 /*
170 * Probable Target failure before we're prepared
171 * to handle it. Generally unexpected.
172 */
173 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
174 ("%s: Early firmware event indicated\n",
175 __func__));
176 }
177 } else {
Houston Hoffman2c32cf62016-03-14 21:12:00 -0700178 if (Q_TARGET_ACCESS_END(scn) < 0)
179 return ATH_ISR_SCHED;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800180 }
181
182 return ATH_ISR_SCHED;
183}
184#else
185irqreturn_t hif_fw_interrupt_handler(int irq, void *arg)
186{
187 return ATH_ISR_SCHED;
188}
189#endif /* #ifdef QCA_WIFI_3_0 */
190
191/**
192 * hif_get_targetdef(): hif_get_targetdef
193 * @scn: scn
194 *
195 * Return: void *
196 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530197void *hif_get_targetdef(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800198{
Komal Seelam644263d2016-02-22 20:45:49 +0530199 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
200
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800201 return scn->targetdef;
202}
203
204/**
205 * hif_vote_link_down(): unvote for link up
206 *
207 * Call hif_vote_link_down to release a previous request made using
208 * hif_vote_link_up. A hif_vote_link_down call should only be made
209 * after a corresponding hif_vote_link_up, otherwise you could be
210 * negating a vote from another source. When no votes are present
211 * hif will not guarantee the linkstate after hif_bus_suspend.
212 *
213 * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
214 * and initialization deinitialization sequencences.
215 *
216 * Return: n/a
217 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530218void hif_vote_link_down(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800219{
Komal Seelam644263d2016-02-22 20:45:49 +0530220 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530221 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800222
223 scn->linkstate_vote--;
224 if (scn->linkstate_vote == 0)
Houston Hoffmancceec342015-11-11 11:37:20 -0800225 hif_bus_prevent_linkdown(scn, false);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800226}
227
228/**
229 * hif_vote_link_up(): vote to prevent bus from suspending
230 *
231 * Makes hif guarantee that fw can message the host normally
232 * durring suspend.
233 *
234 * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
235 * and initialization deinitialization sequencences.
236 *
237 * Return: n/a
238 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530239void hif_vote_link_up(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800240{
Komal Seelam644263d2016-02-22 20:45:49 +0530241 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530242 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800243
244 scn->linkstate_vote++;
245 if (scn->linkstate_vote == 1)
Houston Hoffmancceec342015-11-11 11:37:20 -0800246 hif_bus_prevent_linkdown(scn, true);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800247}
248
249/**
250 * hif_can_suspend_link(): query if hif is permitted to suspend the link
251 *
252 * Hif will ensure that the link won't be suspended if the upperlayers
253 * don't want it to.
254 *
255 * SYNCHRONIZATION: MC thread is stopped before bus suspend thus
256 * we don't need extra locking to ensure votes dont change while
257 * we are in the process of suspending or resuming.
258 *
259 * Return: false if hif will guarantee link up durring suspend.
260 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530261bool hif_can_suspend_link(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800262{
Komal Seelam644263d2016-02-22 20:45:49 +0530263 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530264 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800265
266 return scn->linkstate_vote == 0;
267}
268
269/**
270 * hif_hia_item_address(): hif_hia_item_address
271 * @target_type: target_type
272 * @item_offset: item_offset
273 *
274 * Return: n/a
275 */
276uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
277{
278 switch (target_type) {
279 case TARGET_TYPE_AR6002:
280 return AR6002_HOST_INTEREST_ADDRESS + item_offset;
281 case TARGET_TYPE_AR6003:
282 return AR6003_HOST_INTEREST_ADDRESS + item_offset;
283 case TARGET_TYPE_AR6004:
284 return AR6004_HOST_INTEREST_ADDRESS + item_offset;
285 case TARGET_TYPE_AR6006:
286 return AR6006_HOST_INTEREST_ADDRESS + item_offset;
287 case TARGET_TYPE_AR9888:
288 return AR9888_HOST_INTEREST_ADDRESS + item_offset;
289 case TARGET_TYPE_AR6320:
290 case TARGET_TYPE_AR6320V2:
291 return AR6320_HOST_INTEREST_ADDRESS + item_offset;
292 case TARGET_TYPE_QCA6180:
293 return QCA6180_HOST_INTEREST_ADDRESS + item_offset;
294 case TARGET_TYPE_ADRASTEA:
295 /* ADRASTEA doesn't have a host interest address */
296 ASSERT(0);
297 return 0;
298 default:
299 ASSERT(0);
300 return 0;
301 }
302}
303
304/**
305 * hif_max_num_receives_reached() - check max receive is reached
Komal Seelambd7c51d2016-02-24 10:27:30 +0530306 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800307 * @count: unsigned int.
308 *
309 * Output check status as bool
310 *
311 * Return: bool
312 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530313bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800314{
Komal Seelambd7c51d2016-02-24 10:27:30 +0530315 if (WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800316 return count > 120;
317 else
318 return count > MAX_NUM_OF_RECEIVES;
319}
320
321/**
322 * init_buffer_count() - initial buffer count
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530323 * @maxSize: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800324 *
325 * routine to modify the initial buffer count to be allocated on an os
326 * platform basis. Platform owner will need to modify this as needed
327 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530328 * Return: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800329 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530330qdf_size_t init_buffer_count(qdf_size_t maxSize)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800331{
332 return maxSize;
333}
334
335/**
Nirav Shahd7f91592016-04-21 14:18:43 +0530336 * hif_save_htc_htt_config_endpoint() - save htt_tx_endpoint
337 * @hif_ctx: hif context
338 * @htc_htt_tx_endpoint: htt_tx_endpoint
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800339 *
340 * Return: void
341 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530342void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
Nirav Shahd7f91592016-04-21 14:18:43 +0530343 int htc_htt_tx_endpoint)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800344{
Komal Seelam644263d2016-02-22 20:45:49 +0530345 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800346
347 if (!scn) {
348 HIF_ERROR("%s: error: scn or scn->hif_sc is NULL!",
349 __func__);
350 return;
351 }
352
Nirav Shahd7f91592016-04-21 14:18:43 +0530353 scn->htc_htt_tx_endpoint = htc_htt_tx_endpoint;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800354}
355
356/**
357 * hif_get_hw_name(): get a human readable name for the hardware
Komal Seelam91553ce2016-01-27 18:57:10 +0530358 * @info: Target Info
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800359 *
Komal Seelam91553ce2016-01-27 18:57:10 +0530360 * Return: human readable name for the underlying wifi hardware.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800361 */
Komal Seelam91553ce2016-01-27 18:57:10 +0530362static const char *hif_get_hw_name(struct hif_target_info *info)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800363{
364 int i;
Komal Seelam91553ce2016-01-27 18:57:10 +0530365
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800366 for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
Komal Seelam91553ce2016-01-27 18:57:10 +0530367 if (info->target_version == qwlan_hw_list[i].id &&
368 info->target_revision == qwlan_hw_list[i].subid) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800369 return qwlan_hw_list[i].name;
370 }
371 }
372
373 return "Unknown Device";
374}
375
376/**
377 * hif_get_hw_info(): hif_get_hw_info
378 * @scn: scn
379 * @version: version
380 * @revision: revision
381 *
382 * Return: n/a
383 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530384void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800385 const char **target_name)
386{
Komal Seelam91553ce2016-01-27 18:57:10 +0530387 struct hif_target_info *info = hif_get_target_info_handle(scn);
388 *version = info->target_version;
389 *revision = info->target_revision;
390 *target_name = hif_get_hw_name(info);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800391}
392
393/**
394 * hif_open(): hif_open
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530395 * @qdf_ctx: QDF Context
Komal Seelambd7c51d2016-02-24 10:27:30 +0530396 * @mode: Driver Mode
397 * @bus_type: Bus Type
398 * @cbk: CDS Callbacks
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800399 *
Komal Seelambd7c51d2016-02-24 10:27:30 +0530400 * API to open HIF Context
401 *
402 * Return: HIF Opaque Pointer
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800403 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530404struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode,
405 enum qdf_bus_type bus_type,
Komal Seelam75080122016-03-02 15:18:25 +0530406 struct hif_driver_state_callbacks *cbk)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800407{
Komal Seelam644263d2016-02-22 20:45:49 +0530408 struct hif_softc *scn;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530409 QDF_STATUS status = QDF_STATUS_SUCCESS;
Houston Hoffman162164c2016-03-14 21:12:10 -0700410 int bus_context_size = hif_bus_get_context_size(bus_type);
411
412 if (bus_context_size == 0) {
413 HIF_ERROR("%s: context size 0 not allowed", __func__);
414 return NULL;
415 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800416
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530417 scn = (struct hif_softc *)qdf_mem_malloc(bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530418 if (!scn) {
419 HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
420 __func__, bus_context_size);
421 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800422 }
423
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530424 qdf_mem_zero(scn, bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530425
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530426 scn->qdf_dev = qdf_ctx;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530427 scn->hif_con_param = mode;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530428 qdf_atomic_init(&scn->active_tasklet_cnt);
429 qdf_atomic_init(&scn->link_suspended);
430 qdf_atomic_init(&scn->tasklet_from_intr);
Komal Seelam75080122016-03-02 15:18:25 +0530431 qdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_driver_state_callbacks));
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800432
433 status = hif_bus_open(scn, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530434 if (status != QDF_STATUS_SUCCESS) {
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800435 HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
436 __func__, status, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530437 qdf_mem_free(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530438 scn = NULL;
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800439 }
440
Komal Seelambd7c51d2016-02-24 10:27:30 +0530441 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800442}
443
444/**
445 * hif_close(): hif_close
446 * @hif_ctx: hif_ctx
447 *
448 * Return: n/a
449 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530450void hif_close(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800451{
Komal Seelam644263d2016-02-22 20:45:49 +0530452 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800453
454 if (scn == NULL) {
Komal Seelam5584a7c2016-02-24 19:22:48 +0530455 HIF_ERROR("%s: hif_opaque_softc is NULL", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800456 return;
457 }
458
459 if (scn->athdiag_procfs_inited) {
460 athdiag_procfs_remove();
461 scn->athdiag_procfs_inited = false;
462 }
463
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800464 hif_bus_close(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530465 qdf_mem_free(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800466}
467
468/**
469 * hif_enable(): hif_enable
470 * @hif_ctx: hif_ctx
471 * @dev: dev
472 * @bdev: bus dev
473 * @bid: bus ID
474 * @bus_type: bus type
475 * @type: enable type
476 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530477 * Return: QDF_STATUS
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800478 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530479QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800480 void *bdev, const hif_bus_id *bid,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530481 enum qdf_bus_type bus_type,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800482 enum hif_enable_type type)
483{
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530484 QDF_STATUS status;
Komal Seelam644263d2016-02-22 20:45:49 +0530485 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800486
487 if (scn == NULL) {
488 HIF_ERROR("%s: hif_ctx = NULL", __func__);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530489 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800490 }
491
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800492 status = hif_enable_bus(scn, dev, bdev, bid, type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530493 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800494 HIF_ERROR("%s: hif_enable_bus error = %d",
495 __func__, status);
496 return status;
497 }
498
499 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530500 hif_vote_link_up(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800501
Houston Hoffman108da402016-03-14 21:11:24 -0700502 if (hif_bus_configure(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800503 HIF_ERROR("%s: Target probe failed.", __func__);
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530504 hif_disable_bus(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530505 status = QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800506 return status;
507 }
Houston Hoffman108da402016-03-14 21:11:24 -0700508
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800509 /*
510 * Flag to avoid potential unallocated memory access from MSI
511 * interrupt handler which could get scheduled as soon as MSI
512 * is enabled, i.e to take care of the race due to the order
513 * in where MSI is enabled before the memory, that will be
514 * in interrupt handlers, is allocated.
515 */
516
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800517 scn->hif_init_done = true;
518
519 HIF_TRACE("%s: X OK", __func__);
520
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530521 return QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800522}
523
524/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800525 * hif_wlan_disable(): call the platform driver to disable wlan
Komal Seelambd7c51d2016-02-24 10:27:30 +0530526 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800527 *
528 * This function passes the con_mode to platform driver to disable
529 * wlan.
530 *
531 * Return: void
532 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530533void hif_wlan_disable(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800534{
535 enum icnss_driver_mode mode;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530536 uint32_t con_mode = hif_get_conparam(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800537
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530538 if (QDF_GLOBAL_FTM_MODE == con_mode)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800539 mode = ICNSS_FTM;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530540 else if (WLAN_IS_EPPING_ENABLED(con_mode))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800541 mode = ICNSS_EPPING;
Peng Xu7b962532015-10-02 17:17:03 -0700542 else
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800543 mode = ICNSS_MISSION;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800544
545 icnss_wlan_disable(mode);
546}
547
Komal Seelam5584a7c2016-02-24 19:22:48 +0530548void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800549{
Komal Seelam644263d2016-02-22 20:45:49 +0530550 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800551
552 if (!scn)
553 return;
554
555 hif_nointrs(scn);
556 if (scn->hif_init_done == false)
Komal Seelam644263d2016-02-22 20:45:49 +0530557 hif_shut_down_device(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800558 else
Komal Seelam644263d2016-02-22 20:45:49 +0530559 hif_stop(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800560
561 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530562 hif_vote_link_down(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800563
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530564 hif_disable_bus(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800565
Komal Seelambd7c51d2016-02-24 10:27:30 +0530566 hif_wlan_disable(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800567
568 scn->notice_send = false;
569
570 HIF_INFO("%s: X", __func__);
571}
572
573
574/**
Govind Singh2443fb32016-01-13 17:44:48 +0530575 * hif_crash_shutdown_dump_bus_register() - dump bus registers
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800576 * @hif_ctx: hif_ctx
577 *
578 * Return: n/a
579 */
580#if defined(TARGET_RAMDUMP_AFTER_KERNEL_PANIC) \
Houston Hoffmanbc693492016-03-14 21:11:41 -0700581&& defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800582
Govind Singh2443fb32016-01-13 17:44:48 +0530583static void hif_crash_shutdown_dump_bus_register(void *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800584{
Komal Seelam5584a7c2016-02-24 19:22:48 +0530585 struct hif_opaque_softc *scn = hif_ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800586
Govind Singh2443fb32016-01-13 17:44:48 +0530587 if (hif_check_soc_status(scn))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800588 return;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800589
Govind Singh2443fb32016-01-13 17:44:48 +0530590 if (hif_dump_registers(scn))
591 HIF_ERROR("Failed to dump bus registers!");
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800592}
593
594/**
595 * hif_crash_shutdown(): hif_crash_shutdown
596 *
597 * This function is called by the platform driver to dump CE registers
598 *
599 * @hif_ctx: hif_ctx
600 *
601 * Return: n/a
602 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530603void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800604{
Komal Seelam644263d2016-02-22 20:45:49 +0530605 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800606
Houston Hoffmanbc693492016-03-14 21:11:41 -0700607 if (!hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800608 return;
609
Houston Hoffmanbc693492016-03-14 21:11:41 -0700610 if (scn->bus_type == QDF_BUS_TYPE_SNOC) {
611 HIF_INFO_MED("%s: RAM dump disabled for bustype %d",
612 __func__, scn->bus_type);
613 return;
614 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800615
616 if (OL_TRGET_STATUS_RESET == scn->target_status) {
617 HIF_INFO_MED("%s: Target is already asserted, ignore!",
618 __func__);
619 return;
620 }
621
Komal Seelambd7c51d2016-02-24 10:27:30 +0530622 if (hif_is_load_or_unload_in_progress(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800623 HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
624 return;
625 }
626
Govind Singh2443fb32016-01-13 17:44:48 +0530627 hif_crash_shutdown_dump_bus_register(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800628
Komal Seelam644263d2016-02-22 20:45:49 +0530629 if (ol_copy_ramdump(hif_ctx))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800630 goto out;
631
632 HIF_INFO_MED("%s: RAM dump collecting completed!", __func__);
633
634out:
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800635 return;
636}
637#else
Komal Seelam5584a7c2016-02-24 19:22:48 +0530638void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800639{
640 HIF_INFO_MED("%s: Collecting target RAM dump disabled",
641 __func__);
642 return;
643}
644#endif /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
645
646#ifdef QCA_WIFI_3_0
647/**
648 * hif_check_fw_reg(): hif_check_fw_reg
649 * @scn: scn
650 * @state:
651 *
652 * Return: int
653 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530654int hif_check_fw_reg(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800655{
656 return 0;
657}
658#endif
659
660#ifdef IPA_OFFLOAD
661/**
662 * hif_read_phy_mem_base(): hif_read_phy_mem_base
663 * @scn: scn
664 * @phy_mem_base: physical mem base
665 *
666 * Return: n/a
667 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530668void hif_read_phy_mem_base(struct hif_softc *scn, qdf_dma_addr_t *phy_mem_base)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800669{
670 *phy_mem_base = scn->mem_pa;
671}
672#endif /* IPA_OFFLOAD */
673
674/**
675 * hif_get_device_type(): hif_get_device_type
676 * @device_id: device_id
677 * @revision_id: revision_id
678 * @hif_type: returned hif_type
679 * @target_type: returned target_type
680 *
681 * Return: int
682 */
683int hif_get_device_type(uint32_t device_id,
684 uint32_t revision_id,
685 uint32_t *hif_type, uint32_t *target_type)
686{
687 int ret = 0;
688
689 switch (device_id) {
690#ifdef QCA_WIFI_3_0_ADRASTEA
691 case ADRASTEA_DEVICE_ID:
692 case ADRASTEA_DEVICE_ID_P2_E12:
693
694 *hif_type = HIF_TYPE_ADRASTEA;
695 *target_type = TARGET_TYPE_ADRASTEA;
696 break;
697#else
698 case QCA6180_DEVICE_ID:
699 *hif_type = HIF_TYPE_QCA6180;
700 *target_type = TARGET_TYPE_QCA6180;
701 break;
702#endif
703
704 case AR9888_DEVICE_ID:
705 *hif_type = HIF_TYPE_AR9888;
706 *target_type = TARGET_TYPE_AR9888;
707 break;
708
709 case AR6320_DEVICE_ID:
710 switch (revision_id) {
711 case AR6320_FW_1_1:
712 case AR6320_FW_1_3:
713 *hif_type = HIF_TYPE_AR6320;
714 *target_type = TARGET_TYPE_AR6320;
715 break;
716
717 case AR6320_FW_2_0:
718 case AR6320_FW_3_0:
719 case AR6320_FW_3_2:
720 *hif_type = HIF_TYPE_AR6320V2;
721 *target_type = TARGET_TYPE_AR6320V2;
722 break;
723
724 default:
725 HIF_ERROR("%s: error - dev_id = 0x%x, rev_id = 0x%x",
726 __func__, device_id, revision_id);
727 ret = -ENODEV;
728 goto end;
729 }
730 break;
731
732 default:
733 HIF_ERROR("%s: Unsupported device ID!", __func__);
734 ret = -ENODEV;
735 break;
736 }
737end:
738 return ret;
739}
Komal Seelam91553ce2016-01-27 18:57:10 +0530740
741/**
Houston Hoffman26352592016-03-14 21:11:43 -0700742 * hif_needs_bmi() - return true if the soc needs bmi through the driver
743 * @hif_ctx: hif context
744 *
745 * Return: true if the soc needs driver bmi otherwise false
746 */
747bool hif_needs_bmi(struct hif_opaque_softc *hif_ctx)
748{
749 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx);
750 return hif_sc->bus_type != QDF_BUS_TYPE_SNOC;
751}
752
753/**
Houston Hoffman60a1eeb2016-03-14 21:11:44 -0700754 * hif_get_bus_type() - return the bus type
755 *
756 * Return: enum qdf_bus_type
757 */
758enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl)
759{
760 struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
761 return scn->bus_type;
762}
763
764/**
Komal Seelam91553ce2016-01-27 18:57:10 +0530765 * Target info and ini parameters are global to the driver
766 * Hence these structures are exposed to all the modules in
767 * the driver and they don't need to maintains multiple copies
768 * of the same info, instead get the handle from hif and
769 * modify them in hif
770 */
771
772/**
773 * hif_get_ini_handle() - API to get hif_config_param handle
Komal Seelam644263d2016-02-22 20:45:49 +0530774 * @hif_ctx: HIF Context
Komal Seelam91553ce2016-01-27 18:57:10 +0530775 *
776 * Return: pointer to hif_config_info
777 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530778struct hif_config_info *hif_get_ini_handle(struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530779{
Komal Seelam644263d2016-02-22 20:45:49 +0530780 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
781
782 return &sc->hif_config;
Komal Seelam91553ce2016-01-27 18:57:10 +0530783}
784
785/**
786 * hif_get_target_info_handle() - API to get hif_target_info handle
Komal Seelam644263d2016-02-22 20:45:49 +0530787 * @hif_ctx: HIF context
Komal Seelam91553ce2016-01-27 18:57:10 +0530788 *
789 * Return: Pointer to hif_target_info
790 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530791struct hif_target_info *hif_get_target_info_handle(
792 struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530793{
Komal Seelam644263d2016-02-22 20:45:49 +0530794 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
795
796 return &sc->target_info;
797
Komal Seelam91553ce2016-01-27 18:57:10 +0530798}
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530799
800#if defined(FEATURE_LRO)
801/**
802 * hif_lro_flush_cb_register - API to register for LRO Flush Callback
803 * @scn: HIF Context
804 * @handler: Function pointer to be called by HIF
805 * @data: Private data to be used by the module registering to HIF
806 *
807 * Return: void
808 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530809void hif_lro_flush_cb_register(struct hif_opaque_softc *scn,
810 void (handler)(void *), void *data)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530811{
812 ce_lro_flush_cb_register(scn, handler, data);
813}
814
815/**
816 * hif_lro_flush_cb_deregister - API to deregister for LRO Flush Callbacks
817 * @scn: HIF Context
818 *
819 * Return: void
820 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530821void hif_lro_flush_cb_deregister(struct hif_opaque_softc *scn)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530822{
823 ce_lro_flush_cb_deregister(scn);
824}
825#endif
Komal Seelam644263d2016-02-22 20:45:49 +0530826
827/**
828 * hif_get_target_status - API to get target status
829 * @hif_ctx: HIF Context
830 *
831 * Return: enum ol_target_status
832 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530833ol_target_status hif_get_target_status(struct hif_opaque_softc *hif_ctx)
Komal Seelam644263d2016-02-22 20:45:49 +0530834{
835 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
836
837 return scn->target_status;
838}
839
840/**
Komal Seelama5911d32016-02-24 19:21:59 +0530841 * hif_set_target_status() - API to set target status
Komal Seelam644263d2016-02-22 20:45:49 +0530842 * @hif_ctx: HIF Context
843 * @status: Target Status
844 *
845 * Return: void
846 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530847void hif_set_target_status(struct hif_opaque_softc *hif_ctx,
848 ol_target_status status)
Komal Seelam644263d2016-02-22 20:45:49 +0530849{
850 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
851
852 scn->target_status = status;
853}
Komal Seelama5911d32016-02-24 19:21:59 +0530854
855/**
856 * hif_init_ini_config() - API to initialize HIF configuration parameters
857 * @hif_ctx: HIF Context
858 * @cfg: HIF Configuration
859 *
860 * Return: void
861 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530862void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
863 struct hif_config_info *cfg)
Komal Seelama5911d32016-02-24 19:21:59 +0530864{
865 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
866
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530867 qdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
Komal Seelama5911d32016-02-24 19:21:59 +0530868}
Komal Seelambd7c51d2016-02-24 10:27:30 +0530869
870/**
871 * hif_get_conparam() - API to get driver mode in HIF
872 * @scn: HIF Context
873 *
874 * Return: driver mode of operation
875 */
876uint32_t hif_get_conparam(struct hif_softc *scn)
877{
878 if (!scn)
879 return 0;
880
881 return scn->hif_con_param;
882}
883
884/**
885 * hif_get_callbacks_handle() - API to get callbacks Handle
886 * @scn: HIF Context
887 *
888 * Return: pointer to HIF Callbacks
889 */
Komal Seelam75080122016-03-02 15:18:25 +0530890struct hif_driver_state_callbacks *hif_get_callbacks_handle(struct hif_softc *scn)
Komal Seelambd7c51d2016-02-24 10:27:30 +0530891{
892 return &scn->callbacks;
893}
894
895/**
896 * hif_is_driver_unloading() - API to query upper layers if driver is unloading
897 * @scn: HIF Context
898 *
899 * Return: True/False
900 */
901bool hif_is_driver_unloading(struct hif_softc *scn)
902{
Komal Seelam75080122016-03-02 15:18:25 +0530903 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530904
905 if (cbk && cbk->is_driver_unloading)
906 return cbk->is_driver_unloading(cbk->context);
907
908 return false;
909}
910
911/**
912 * hif_is_load_or_unload_in_progress() - API to query upper layers if
913 * load/unload in progress
914 * @scn: HIF Context
915 *
916 * Return: True/False
917 */
918bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
919{
Komal Seelam75080122016-03-02 15:18:25 +0530920 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530921
922 if (cbk && cbk->is_load_unload_in_progress)
923 return cbk->is_load_unload_in_progress(cbk->context);
924
925 return false;
926}
927
928/**
929 * hif_is_recovery_in_progress() - API to query upper layers if recovery in
930 * progress
931 * @scn: HIF Context
932 *
933 * Return: True/False
934 */
935bool hif_is_recovery_in_progress(struct hif_softc *scn)
936{
Komal Seelam75080122016-03-02 15:18:25 +0530937 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530938
939 if (cbk && cbk->is_recovery_in_progress)
940 return cbk->is_recovery_in_progress(cbk->context);
941
942 return false;
943}