blob: 03c9f76a310311bb4b26160b48927514c3478f67 [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
Houston Hoffman4f529982016-05-05 16:11:04 -0700266#ifndef CONFIG_WIN
267#define QCA9984_HOST_INTEREST_ADDRESS -1
268#define QCA9888_HOST_INTEREST_ADDRESS -1
269#define IPQ4019_HOST_INTEREST_ADDRESS -1
270#endif
271
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800272/**
273 * hif_hia_item_address(): hif_hia_item_address
274 * @target_type: target_type
275 * @item_offset: item_offset
276 *
277 * Return: n/a
278 */
279uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
280{
281 switch (target_type) {
282 case TARGET_TYPE_AR6002:
283 return AR6002_HOST_INTEREST_ADDRESS + item_offset;
284 case TARGET_TYPE_AR6003:
285 return AR6003_HOST_INTEREST_ADDRESS + item_offset;
286 case TARGET_TYPE_AR6004:
287 return AR6004_HOST_INTEREST_ADDRESS + item_offset;
288 case TARGET_TYPE_AR6006:
289 return AR6006_HOST_INTEREST_ADDRESS + item_offset;
290 case TARGET_TYPE_AR9888:
291 return AR9888_HOST_INTEREST_ADDRESS + item_offset;
292 case TARGET_TYPE_AR6320:
293 case TARGET_TYPE_AR6320V2:
294 return AR6320_HOST_INTEREST_ADDRESS + item_offset;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800295 case TARGET_TYPE_ADRASTEA:
296 /* ADRASTEA doesn't have a host interest address */
297 ASSERT(0);
298 return 0;
299 default:
300 ASSERT(0);
301 return 0;
302 }
303}
304
305/**
306 * hif_max_num_receives_reached() - check max receive is reached
Komal Seelambd7c51d2016-02-24 10:27:30 +0530307 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800308 * @count: unsigned int.
309 *
310 * Output check status as bool
311 *
312 * Return: bool
313 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530314bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800315{
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700316 if (QDF_IS_EPPING_ENABLED(hif_get_conparam(scn)))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800317 return count > 120;
318 else
319 return count > MAX_NUM_OF_RECEIVES;
320}
321
322/**
323 * init_buffer_count() - initial buffer count
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530324 * @maxSize: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800325 *
326 * routine to modify the initial buffer count to be allocated on an os
327 * platform basis. Platform owner will need to modify this as needed
328 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530329 * Return: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800330 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530331qdf_size_t init_buffer_count(qdf_size_t maxSize)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800332{
333 return maxSize;
334}
335
336/**
Nirav Shahd7f91592016-04-21 14:18:43 +0530337 * hif_save_htc_htt_config_endpoint() - save htt_tx_endpoint
338 * @hif_ctx: hif context
339 * @htc_htt_tx_endpoint: htt_tx_endpoint
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800340 *
341 * Return: void
342 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530343void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
Nirav Shahd7f91592016-04-21 14:18:43 +0530344 int htc_htt_tx_endpoint)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800345{
Komal Seelam644263d2016-02-22 20:45:49 +0530346 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800347
348 if (!scn) {
349 HIF_ERROR("%s: error: scn or scn->hif_sc is NULL!",
350 __func__);
351 return;
352 }
353
Nirav Shahd7f91592016-04-21 14:18:43 +0530354 scn->htc_htt_tx_endpoint = htc_htt_tx_endpoint;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800355}
356
Houston Hoffmanec93ab02016-05-03 20:09:55 -0700357static const struct qwlan_hw qwlan_hw_list[] = {
358 {
359 .id = AR6320_REV1_VERSION,
360 .subid = 0,
361 .name = "QCA6174_REV1",
362 },
363 {
364 .id = AR6320_REV1_1_VERSION,
365 .subid = 0x1,
366 .name = "QCA6174_REV1_1",
367 },
368 {
369 .id = AR6320_REV1_3_VERSION,
370 .subid = 0x2,
371 .name = "QCA6174_REV1_3",
372 },
373 {
374 .id = AR6320_REV2_1_VERSION,
375 .subid = 0x4,
376 .name = "QCA6174_REV2_1",
377 },
378 {
379 .id = AR6320_REV2_1_VERSION,
380 .subid = 0x5,
381 .name = "QCA6174_REV2_2",
382 },
383 {
384 .id = AR6320_REV3_VERSION,
385 .subid = 0x6,
386 .name = "QCA6174_REV2.3",
387 },
388 {
389 .id = AR6320_REV3_VERSION,
390 .subid = 0x8,
391 .name = "QCA6174_REV3",
392 },
393 {
394 .id = AR6320_REV3_VERSION,
395 .subid = 0x9,
396 .name = "QCA6174_REV3_1",
397 },
398 {
399 .id = AR6320_REV3_2_VERSION,
400 .subid = 0xA,
401 .name = "AR6320_REV3_2_VERSION",
402 }
403};
404
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800405/**
406 * hif_get_hw_name(): get a human readable name for the hardware
Komal Seelam91553ce2016-01-27 18:57:10 +0530407 * @info: Target Info
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800408 *
Komal Seelam91553ce2016-01-27 18:57:10 +0530409 * Return: human readable name for the underlying wifi hardware.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800410 */
Komal Seelam91553ce2016-01-27 18:57:10 +0530411static const char *hif_get_hw_name(struct hif_target_info *info)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800412{
413 int i;
Komal Seelam91553ce2016-01-27 18:57:10 +0530414
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800415 for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
Komal Seelam91553ce2016-01-27 18:57:10 +0530416 if (info->target_version == qwlan_hw_list[i].id &&
417 info->target_revision == qwlan_hw_list[i].subid) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800418 return qwlan_hw_list[i].name;
419 }
420 }
421
422 return "Unknown Device";
423}
424
425/**
426 * hif_get_hw_info(): hif_get_hw_info
427 * @scn: scn
428 * @version: version
429 * @revision: revision
430 *
431 * Return: n/a
432 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530433void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800434 const char **target_name)
435{
Komal Seelam91553ce2016-01-27 18:57:10 +0530436 struct hif_target_info *info = hif_get_target_info_handle(scn);
437 *version = info->target_version;
438 *revision = info->target_revision;
439 *target_name = hif_get_hw_name(info);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800440}
441
442/**
443 * hif_open(): hif_open
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530444 * @qdf_ctx: QDF Context
Komal Seelambd7c51d2016-02-24 10:27:30 +0530445 * @mode: Driver Mode
446 * @bus_type: Bus Type
447 * @cbk: CDS Callbacks
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800448 *
Komal Seelambd7c51d2016-02-24 10:27:30 +0530449 * API to open HIF Context
450 *
451 * Return: HIF Opaque Pointer
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800452 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530453struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode,
454 enum qdf_bus_type bus_type,
Komal Seelam75080122016-03-02 15:18:25 +0530455 struct hif_driver_state_callbacks *cbk)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800456{
Komal Seelam644263d2016-02-22 20:45:49 +0530457 struct hif_softc *scn;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530458 QDF_STATUS status = QDF_STATUS_SUCCESS;
Houston Hoffman162164c2016-03-14 21:12:10 -0700459 int bus_context_size = hif_bus_get_context_size(bus_type);
460
461 if (bus_context_size == 0) {
462 HIF_ERROR("%s: context size 0 not allowed", __func__);
463 return NULL;
464 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800465
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530466 scn = (struct hif_softc *)qdf_mem_malloc(bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530467 if (!scn) {
468 HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
469 __func__, bus_context_size);
470 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800471 }
472
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530473 qdf_mem_zero(scn, bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530474
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530475 scn->qdf_dev = qdf_ctx;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530476 scn->hif_con_param = mode;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530477 qdf_atomic_init(&scn->active_tasklet_cnt);
478 qdf_atomic_init(&scn->link_suspended);
479 qdf_atomic_init(&scn->tasklet_from_intr);
Komal Seelam75080122016-03-02 15:18:25 +0530480 qdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_driver_state_callbacks));
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800481
482 status = hif_bus_open(scn, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530483 if (status != QDF_STATUS_SUCCESS) {
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800484 HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
485 __func__, status, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530486 qdf_mem_free(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530487 scn = NULL;
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800488 }
489
Komal Seelambd7c51d2016-02-24 10:27:30 +0530490 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800491}
492
493/**
494 * hif_close(): hif_close
495 * @hif_ctx: hif_ctx
496 *
497 * Return: n/a
498 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530499void hif_close(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800500{
Komal Seelam644263d2016-02-22 20:45:49 +0530501 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800502
503 if (scn == NULL) {
Komal Seelam5584a7c2016-02-24 19:22:48 +0530504 HIF_ERROR("%s: hif_opaque_softc is NULL", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800505 return;
506 }
507
508 if (scn->athdiag_procfs_inited) {
509 athdiag_procfs_remove();
510 scn->athdiag_procfs_inited = false;
511 }
512
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800513 hif_bus_close(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530514 qdf_mem_free(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800515}
516
517/**
518 * hif_enable(): hif_enable
519 * @hif_ctx: hif_ctx
520 * @dev: dev
521 * @bdev: bus dev
522 * @bid: bus ID
523 * @bus_type: bus type
524 * @type: enable type
525 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530526 * Return: QDF_STATUS
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800527 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530528QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800529 void *bdev, const hif_bus_id *bid,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530530 enum qdf_bus_type bus_type,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800531 enum hif_enable_type type)
532{
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530533 QDF_STATUS status;
Komal Seelam644263d2016-02-22 20:45:49 +0530534 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800535
536 if (scn == NULL) {
537 HIF_ERROR("%s: hif_ctx = NULL", __func__);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530538 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800539 }
540
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800541 status = hif_enable_bus(scn, dev, bdev, bid, type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530542 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800543 HIF_ERROR("%s: hif_enable_bus error = %d",
544 __func__, status);
545 return status;
546 }
547
548 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530549 hif_vote_link_up(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800550
Houston Hoffman108da402016-03-14 21:11:24 -0700551 if (hif_bus_configure(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800552 HIF_ERROR("%s: Target probe failed.", __func__);
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530553 hif_disable_bus(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530554 status = QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800555 return status;
556 }
Houston Hoffman108da402016-03-14 21:11:24 -0700557
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800558 /*
559 * Flag to avoid potential unallocated memory access from MSI
560 * interrupt handler which could get scheduled as soon as MSI
561 * is enabled, i.e to take care of the race due to the order
562 * in where MSI is enabled before the memory, that will be
563 * in interrupt handlers, is allocated.
564 */
565
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800566 scn->hif_init_done = true;
567
568 HIF_TRACE("%s: X OK", __func__);
569
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530570 return QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800571}
572
573/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800574 * hif_wlan_disable(): call the platform driver to disable wlan
Komal Seelambd7c51d2016-02-24 10:27:30 +0530575 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800576 *
577 * This function passes the con_mode to platform driver to disable
578 * wlan.
579 *
580 * Return: void
581 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530582void hif_wlan_disable(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800583{
584 enum icnss_driver_mode mode;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530585 uint32_t con_mode = hif_get_conparam(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800586
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530587 if (QDF_GLOBAL_FTM_MODE == con_mode)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800588 mode = ICNSS_FTM;
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700589 else if (QDF_IS_EPPING_ENABLED(con_mode))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800590 mode = ICNSS_EPPING;
Peng Xu7b962532015-10-02 17:17:03 -0700591 else
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800592 mode = ICNSS_MISSION;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800593
594 icnss_wlan_disable(mode);
595}
596
Komal Seelam5584a7c2016-02-24 19:22:48 +0530597void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800598{
Komal Seelam644263d2016-02-22 20:45:49 +0530599 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800600
601 if (!scn)
602 return;
603
604 hif_nointrs(scn);
605 if (scn->hif_init_done == false)
Komal Seelam644263d2016-02-22 20:45:49 +0530606 hif_shut_down_device(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800607 else
Komal Seelam644263d2016-02-22 20:45:49 +0530608 hif_stop(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800609
610 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530611 hif_vote_link_down(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800612
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530613 hif_disable_bus(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800614
Komal Seelambd7c51d2016-02-24 10:27:30 +0530615 hif_wlan_disable(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800616
617 scn->notice_send = false;
618
619 HIF_INFO("%s: X", __func__);
620}
621
622
623/**
Govind Singh2443fb32016-01-13 17:44:48 +0530624 * hif_crash_shutdown_dump_bus_register() - dump bus registers
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800625 * @hif_ctx: hif_ctx
626 *
627 * Return: n/a
628 */
629#if defined(TARGET_RAMDUMP_AFTER_KERNEL_PANIC) \
Houston Hoffmanbc693492016-03-14 21:11:41 -0700630&& defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800631
Govind Singh2443fb32016-01-13 17:44:48 +0530632static void hif_crash_shutdown_dump_bus_register(void *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800633{
Komal Seelam5584a7c2016-02-24 19:22:48 +0530634 struct hif_opaque_softc *scn = hif_ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800635
Govind Singh2443fb32016-01-13 17:44:48 +0530636 if (hif_check_soc_status(scn))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800637 return;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800638
Govind Singh2443fb32016-01-13 17:44:48 +0530639 if (hif_dump_registers(scn))
640 HIF_ERROR("Failed to dump bus registers!");
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800641}
642
643/**
644 * hif_crash_shutdown(): hif_crash_shutdown
645 *
646 * This function is called by the platform driver to dump CE registers
647 *
648 * @hif_ctx: hif_ctx
649 *
650 * Return: n/a
651 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530652void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800653{
Komal Seelam644263d2016-02-22 20:45:49 +0530654 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800655
Houston Hoffmanbc693492016-03-14 21:11:41 -0700656 if (!hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800657 return;
658
Houston Hoffmanbc693492016-03-14 21:11:41 -0700659 if (scn->bus_type == QDF_BUS_TYPE_SNOC) {
660 HIF_INFO_MED("%s: RAM dump disabled for bustype %d",
661 __func__, scn->bus_type);
662 return;
663 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800664
Komal Seelam6ee55902016-04-11 17:11:07 +0530665 if (TARGET_STATUS_RESET == scn->target_status) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800666 HIF_INFO_MED("%s: Target is already asserted, ignore!",
667 __func__);
668 return;
669 }
670
Komal Seelambd7c51d2016-02-24 10:27:30 +0530671 if (hif_is_load_or_unload_in_progress(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800672 HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
673 return;
674 }
675
Govind Singh2443fb32016-01-13 17:44:48 +0530676 hif_crash_shutdown_dump_bus_register(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800677
Komal Seelam644263d2016-02-22 20:45:49 +0530678 if (ol_copy_ramdump(hif_ctx))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800679 goto out;
680
681 HIF_INFO_MED("%s: RAM dump collecting completed!", __func__);
682
683out:
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800684 return;
685}
686#else
Komal Seelam5584a7c2016-02-24 19:22:48 +0530687void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800688{
689 HIF_INFO_MED("%s: Collecting target RAM dump disabled",
690 __func__);
691 return;
692}
693#endif /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
694
695#ifdef QCA_WIFI_3_0
696/**
697 * hif_check_fw_reg(): hif_check_fw_reg
698 * @scn: scn
699 * @state:
700 *
701 * Return: int
702 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530703int hif_check_fw_reg(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800704{
705 return 0;
706}
707#endif
708
709#ifdef IPA_OFFLOAD
710/**
711 * hif_read_phy_mem_base(): hif_read_phy_mem_base
712 * @scn: scn
713 * @phy_mem_base: physical mem base
714 *
715 * Return: n/a
716 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530717void hif_read_phy_mem_base(struct hif_softc *scn, qdf_dma_addr_t *phy_mem_base)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800718{
719 *phy_mem_base = scn->mem_pa;
720}
721#endif /* IPA_OFFLOAD */
722
723/**
724 * hif_get_device_type(): hif_get_device_type
725 * @device_id: device_id
726 * @revision_id: revision_id
727 * @hif_type: returned hif_type
728 * @target_type: returned target_type
729 *
730 * Return: int
731 */
732int hif_get_device_type(uint32_t device_id,
733 uint32_t revision_id,
734 uint32_t *hif_type, uint32_t *target_type)
735{
736 int ret = 0;
737
738 switch (device_id) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800739 case ADRASTEA_DEVICE_ID:
740 case ADRASTEA_DEVICE_ID_P2_E12:
741
742 *hif_type = HIF_TYPE_ADRASTEA;
743 *target_type = TARGET_TYPE_ADRASTEA;
744 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800745
746 case AR9888_DEVICE_ID:
747 *hif_type = HIF_TYPE_AR9888;
748 *target_type = TARGET_TYPE_AR9888;
749 break;
750
751 case AR6320_DEVICE_ID:
752 switch (revision_id) {
753 case AR6320_FW_1_1:
754 case AR6320_FW_1_3:
755 *hif_type = HIF_TYPE_AR6320;
756 *target_type = TARGET_TYPE_AR6320;
757 break;
758
759 case AR6320_FW_2_0:
760 case AR6320_FW_3_0:
761 case AR6320_FW_3_2:
762 *hif_type = HIF_TYPE_AR6320V2;
763 *target_type = TARGET_TYPE_AR6320V2;
764 break;
765
766 default:
767 HIF_ERROR("%s: error - dev_id = 0x%x, rev_id = 0x%x",
768 __func__, device_id, revision_id);
769 ret = -ENODEV;
770 goto end;
771 }
772 break;
773
774 default:
775 HIF_ERROR("%s: Unsupported device ID!", __func__);
776 ret = -ENODEV;
777 break;
778 }
779end:
780 return ret;
781}
Komal Seelam91553ce2016-01-27 18:57:10 +0530782
783/**
Houston Hoffman26352592016-03-14 21:11:43 -0700784 * hif_needs_bmi() - return true if the soc needs bmi through the driver
785 * @hif_ctx: hif context
786 *
787 * Return: true if the soc needs driver bmi otherwise false
788 */
789bool hif_needs_bmi(struct hif_opaque_softc *hif_ctx)
790{
791 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx);
792 return hif_sc->bus_type != QDF_BUS_TYPE_SNOC;
793}
794
795/**
Houston Hoffman60a1eeb2016-03-14 21:11:44 -0700796 * hif_get_bus_type() - return the bus type
797 *
798 * Return: enum qdf_bus_type
799 */
800enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl)
801{
802 struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
803 return scn->bus_type;
804}
805
806/**
Komal Seelam91553ce2016-01-27 18:57:10 +0530807 * Target info and ini parameters are global to the driver
808 * Hence these structures are exposed to all the modules in
809 * the driver and they don't need to maintains multiple copies
810 * of the same info, instead get the handle from hif and
811 * modify them in hif
812 */
813
814/**
815 * hif_get_ini_handle() - API to get hif_config_param handle
Komal Seelam644263d2016-02-22 20:45:49 +0530816 * @hif_ctx: HIF Context
Komal Seelam91553ce2016-01-27 18:57:10 +0530817 *
818 * Return: pointer to hif_config_info
819 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530820struct hif_config_info *hif_get_ini_handle(struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530821{
Komal Seelam644263d2016-02-22 20:45:49 +0530822 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
823
824 return &sc->hif_config;
Komal Seelam91553ce2016-01-27 18:57:10 +0530825}
826
827/**
828 * hif_get_target_info_handle() - API to get hif_target_info handle
Komal Seelam644263d2016-02-22 20:45:49 +0530829 * @hif_ctx: HIF context
Komal Seelam91553ce2016-01-27 18:57:10 +0530830 *
831 * Return: Pointer to hif_target_info
832 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530833struct hif_target_info *hif_get_target_info_handle(
834 struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530835{
Komal Seelam644263d2016-02-22 20:45:49 +0530836 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
837
838 return &sc->target_info;
839
Komal Seelam91553ce2016-01-27 18:57:10 +0530840}
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530841
842#if defined(FEATURE_LRO)
843/**
844 * hif_lro_flush_cb_register - API to register for LRO Flush Callback
845 * @scn: HIF Context
846 * @handler: Function pointer to be called by HIF
847 * @data: Private data to be used by the module registering to HIF
848 *
849 * Return: void
850 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530851void hif_lro_flush_cb_register(struct hif_opaque_softc *scn,
852 void (handler)(void *), void *data)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530853{
854 ce_lro_flush_cb_register(scn, handler, data);
855}
856
857/**
858 * hif_lro_flush_cb_deregister - API to deregister for LRO Flush Callbacks
859 * @scn: HIF Context
860 *
861 * Return: void
862 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530863void hif_lro_flush_cb_deregister(struct hif_opaque_softc *scn)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530864{
865 ce_lro_flush_cb_deregister(scn);
866}
867#endif
Komal Seelam644263d2016-02-22 20:45:49 +0530868
869/**
870 * hif_get_target_status - API to get target status
871 * @hif_ctx: HIF Context
872 *
Komal Seelam6ee55902016-04-11 17:11:07 +0530873 * Return: enum hif_target_status
Komal Seelam644263d2016-02-22 20:45:49 +0530874 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530875enum hif_target_status hif_get_target_status(struct hif_opaque_softc *hif_ctx)
Komal Seelam644263d2016-02-22 20:45:49 +0530876{
877 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
878
879 return scn->target_status;
880}
881
882/**
Komal Seelama5911d32016-02-24 19:21:59 +0530883 * hif_set_target_status() - API to set target status
Komal Seelam644263d2016-02-22 20:45:49 +0530884 * @hif_ctx: HIF Context
885 * @status: Target Status
886 *
887 * Return: void
888 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530889void hif_set_target_status(struct hif_opaque_softc *hif_ctx, enum
890 hif_target_status status)
Komal Seelam644263d2016-02-22 20:45:49 +0530891{
892 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
893
894 scn->target_status = status;
895}
Komal Seelama5911d32016-02-24 19:21:59 +0530896
897/**
898 * hif_init_ini_config() - API to initialize HIF configuration parameters
899 * @hif_ctx: HIF Context
900 * @cfg: HIF Configuration
901 *
902 * Return: void
903 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530904void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
905 struct hif_config_info *cfg)
Komal Seelama5911d32016-02-24 19:21:59 +0530906{
907 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
908
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530909 qdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
Komal Seelama5911d32016-02-24 19:21:59 +0530910}
Komal Seelambd7c51d2016-02-24 10:27:30 +0530911
912/**
913 * hif_get_conparam() - API to get driver mode in HIF
914 * @scn: HIF Context
915 *
916 * Return: driver mode of operation
917 */
918uint32_t hif_get_conparam(struct hif_softc *scn)
919{
920 if (!scn)
921 return 0;
922
923 return scn->hif_con_param;
924}
925
926/**
927 * hif_get_callbacks_handle() - API to get callbacks Handle
928 * @scn: HIF Context
929 *
930 * Return: pointer to HIF Callbacks
931 */
Komal Seelam75080122016-03-02 15:18:25 +0530932struct hif_driver_state_callbacks *hif_get_callbacks_handle(struct hif_softc *scn)
Komal Seelambd7c51d2016-02-24 10:27:30 +0530933{
934 return &scn->callbacks;
935}
936
937/**
938 * hif_is_driver_unloading() - API to query upper layers if driver is unloading
939 * @scn: HIF Context
940 *
941 * Return: True/False
942 */
943bool hif_is_driver_unloading(struct hif_softc *scn)
944{
Komal Seelam75080122016-03-02 15:18:25 +0530945 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530946
947 if (cbk && cbk->is_driver_unloading)
948 return cbk->is_driver_unloading(cbk->context);
949
950 return false;
951}
952
953/**
954 * hif_is_load_or_unload_in_progress() - API to query upper layers if
955 * load/unload in progress
956 * @scn: HIF Context
957 *
958 * Return: True/False
959 */
960bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
961{
Komal Seelam75080122016-03-02 15:18:25 +0530962 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530963
964 if (cbk && cbk->is_load_unload_in_progress)
965 return cbk->is_load_unload_in_progress(cbk->context);
966
967 return false;
968}
969
970/**
971 * hif_is_recovery_in_progress() - API to query upper layers if recovery in
972 * progress
973 * @scn: HIF Context
974 *
975 * Return: True/False
976 */
977bool hif_is_recovery_in_progress(struct hif_softc *scn)
978{
Komal Seelam75080122016-03-02 15:18:25 +0530979 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530980
981 if (cbk && cbk->is_recovery_in_progress)
982 return cbk->is_recovery_in_progress(cbk->context);
983
984 return false;
985}
Houston Hoffman56e0d702016-05-05 17:48:06 -0700986
987/**
988 * hif_batch_send() - API to access hif specific function
989 * ce_batch_send.
990 * @osc: HIF Context
991 * @msdu : list of msdus to be sent
992 * @transfer_id : transfer id
993 * @len : donwloaded length
994 *
995 * Return: list of msds not sent
996 */
997qdf_nbuf_t hif_batch_send(struct hif_opaque_softc *osc, qdf_nbuf_t msdu,
998 uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
999{
1000 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1001 return ce_batch_send((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
1002 len, sendhead);
1003}
1004
1005/**
1006 * hif_update_tx_ring() - API to access hif specific function
1007 * ce_update_tx_ring.
1008 * @osc: HIF Context
1009 * @num_htt_cmpls : number of htt compl received.
1010 *
1011 * Return: void
1012 */
1013void hif_update_tx_ring(struct hif_opaque_softc *osc, u_int32_t num_htt_cmpls)
1014{
1015 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1016 ce_update_tx_ring(ce_tx_hdl, num_htt_cmpls);
1017}
1018
1019
1020/**
1021 * hif_send_single() - API to access hif specific function
1022 * ce_send_single.
1023 * @osc: HIF Context
1024 * @msdu : msdu to be sent
1025 * @transfer_id: transfer id
1026 * @len : downloaded length
1027 *
1028 * Return: msdu sent status
1029 */
1030int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
1031 transfer_id, u_int32_t len)
1032{
1033 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1034 return ce_send_single((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
1035 len);
1036}
1037
1038/**
1039 * hif_send_fast() - API to access hif specific function
1040 * ce_send_fast.
1041 * @osc: HIF Context
1042 * @msdu : array of msdus to be sent
1043 * @num_msdus : number of msdus in an array
1044 * @transfer_id: transfer id
1045 *
1046 * Return: No. of packets that could be sent
1047 */
1048int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t *nbuf_arr,
1049 uint32_t num_msdus, uint32_t transfer_id)
1050{
1051 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1052 return ce_send_fast((struct CE_handle *)ce_tx_hdl, nbuf_arr, num_msdus,
1053 transfer_id);
1054}
1055
1056/**
1057 * hif_pkt_dl_len_set() - API to access hif specific function
1058 * ce_pkt_dl_len_set.
1059 * @osc: HIF Context
1060 * @pkt_download_len: download length
1061 *
1062 * Return: None
1063 */
1064void hif_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len)
1065{
1066 ce_pkt_dl_len_set(hif_sc, pkt_download_len);
1067}
1068
1069/**
1070 * hif_reg_write() - API to access hif specific function
1071 * hif_write32_mb.
1072 * @hif_ctx : HIF Context
1073 * @offset : offset on which value has to be written
1074 * @value : value to be written
1075 *
1076 * Return: None
1077 */
1078void hif_reg_write(struct hif_opaque_softc *hif_ctx, uint32_t offset,
1079 uint32_t value)
1080{
1081 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
1082 hif_write32_mb(scn->mem + offset, value);
1083
1084}
1085
1086/**
1087 * hif_reg_read() - API to access hif specific function
1088 * hif_read32_mb.
1089 * @hif_ctx : HIF Context
1090 * @offset : offset from which value has to be read
1091 *
1092 * Return: Read value
1093 */
1094uint32_t hif_reg_read(struct hif_opaque_softc *hif_ctx, uint32_t offset)
1095{
1096
1097 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
1098 return hif_read32_mb(scn->mem + offset);
1099}