blob: 8510537e43e3e520e2dcbd0fb9a90ed4457f81d6 [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;
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700299 case TARGET_TYPE_AR900B:
300 return AR900B_HOST_INTEREST_ADDRESS + item_offset;
301 case TARGET_TYPE_QCA9984:
302 return QCA9984_HOST_INTEREST_ADDRESS + item_offset;
303 case TARGET_TYPE_QCA9888:
304 return QCA9888_HOST_INTEREST_ADDRESS + item_offset;
305 case TARGET_TYPE_IPQ4019:
306 return IPQ4019_HOST_INTEREST_ADDRESS + item_offset;
307
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800308 default:
309 ASSERT(0);
310 return 0;
311 }
312}
313
314/**
315 * hif_max_num_receives_reached() - check max receive is reached
Komal Seelambd7c51d2016-02-24 10:27:30 +0530316 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800317 * @count: unsigned int.
318 *
319 * Output check status as bool
320 *
321 * Return: bool
322 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530323bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800324{
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700325 if (QDF_IS_EPPING_ENABLED(hif_get_conparam(scn)))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800326 return count > 120;
327 else
328 return count > MAX_NUM_OF_RECEIVES;
329}
330
331/**
332 * init_buffer_count() - initial buffer count
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530333 * @maxSize: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800334 *
335 * routine to modify the initial buffer count to be allocated on an os
336 * platform basis. Platform owner will need to modify this as needed
337 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530338 * Return: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800339 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530340qdf_size_t init_buffer_count(qdf_size_t maxSize)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800341{
342 return maxSize;
343}
344
345/**
Nirav Shahd7f91592016-04-21 14:18:43 +0530346 * hif_save_htc_htt_config_endpoint() - save htt_tx_endpoint
347 * @hif_ctx: hif context
348 * @htc_htt_tx_endpoint: htt_tx_endpoint
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800349 *
350 * Return: void
351 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530352void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
Nirav Shahd7f91592016-04-21 14:18:43 +0530353 int htc_htt_tx_endpoint)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800354{
Komal Seelam644263d2016-02-22 20:45:49 +0530355 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800356
357 if (!scn) {
358 HIF_ERROR("%s: error: scn or scn->hif_sc is NULL!",
359 __func__);
360 return;
361 }
362
Nirav Shahd7f91592016-04-21 14:18:43 +0530363 scn->htc_htt_tx_endpoint = htc_htt_tx_endpoint;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800364}
365
Houston Hoffmanec93ab02016-05-03 20:09:55 -0700366static const struct qwlan_hw qwlan_hw_list[] = {
367 {
368 .id = AR6320_REV1_VERSION,
369 .subid = 0,
370 .name = "QCA6174_REV1",
371 },
372 {
373 .id = AR6320_REV1_1_VERSION,
374 .subid = 0x1,
375 .name = "QCA6174_REV1_1",
376 },
377 {
378 .id = AR6320_REV1_3_VERSION,
379 .subid = 0x2,
380 .name = "QCA6174_REV1_3",
381 },
382 {
383 .id = AR6320_REV2_1_VERSION,
384 .subid = 0x4,
385 .name = "QCA6174_REV2_1",
386 },
387 {
388 .id = AR6320_REV2_1_VERSION,
389 .subid = 0x5,
390 .name = "QCA6174_REV2_2",
391 },
392 {
393 .id = AR6320_REV3_VERSION,
394 .subid = 0x6,
395 .name = "QCA6174_REV2.3",
396 },
397 {
398 .id = AR6320_REV3_VERSION,
399 .subid = 0x8,
400 .name = "QCA6174_REV3",
401 },
402 {
403 .id = AR6320_REV3_VERSION,
404 .subid = 0x9,
405 .name = "QCA6174_REV3_1",
406 },
407 {
408 .id = AR6320_REV3_2_VERSION,
409 .subid = 0xA,
410 .name = "AR6320_REV3_2_VERSION",
411 }
412};
413
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800414/**
415 * hif_get_hw_name(): get a human readable name for the hardware
Komal Seelam91553ce2016-01-27 18:57:10 +0530416 * @info: Target Info
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800417 *
Komal Seelam91553ce2016-01-27 18:57:10 +0530418 * Return: human readable name for the underlying wifi hardware.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800419 */
Komal Seelam91553ce2016-01-27 18:57:10 +0530420static const char *hif_get_hw_name(struct hif_target_info *info)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800421{
422 int i;
Komal Seelam91553ce2016-01-27 18:57:10 +0530423
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800424 for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
Komal Seelam91553ce2016-01-27 18:57:10 +0530425 if (info->target_version == qwlan_hw_list[i].id &&
426 info->target_revision == qwlan_hw_list[i].subid) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800427 return qwlan_hw_list[i].name;
428 }
429 }
430
431 return "Unknown Device";
432}
433
434/**
435 * hif_get_hw_info(): hif_get_hw_info
436 * @scn: scn
437 * @version: version
438 * @revision: revision
439 *
440 * Return: n/a
441 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530442void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800443 const char **target_name)
444{
Komal Seelam91553ce2016-01-27 18:57:10 +0530445 struct hif_target_info *info = hif_get_target_info_handle(scn);
446 *version = info->target_version;
447 *revision = info->target_revision;
448 *target_name = hif_get_hw_name(info);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800449}
450
451/**
452 * hif_open(): hif_open
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530453 * @qdf_ctx: QDF Context
Komal Seelambd7c51d2016-02-24 10:27:30 +0530454 * @mode: Driver Mode
455 * @bus_type: Bus Type
456 * @cbk: CDS Callbacks
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800457 *
Komal Seelambd7c51d2016-02-24 10:27:30 +0530458 * API to open HIF Context
459 *
460 * Return: HIF Opaque Pointer
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800461 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530462struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode,
463 enum qdf_bus_type bus_type,
Komal Seelam75080122016-03-02 15:18:25 +0530464 struct hif_driver_state_callbacks *cbk)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800465{
Komal Seelam644263d2016-02-22 20:45:49 +0530466 struct hif_softc *scn;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530467 QDF_STATUS status = QDF_STATUS_SUCCESS;
Houston Hoffman162164c2016-03-14 21:12:10 -0700468 int bus_context_size = hif_bus_get_context_size(bus_type);
469
470 if (bus_context_size == 0) {
471 HIF_ERROR("%s: context size 0 not allowed", __func__);
472 return NULL;
473 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800474
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530475 scn = (struct hif_softc *)qdf_mem_malloc(bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530476 if (!scn) {
477 HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
478 __func__, bus_context_size);
479 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800480 }
481
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530482 qdf_mem_zero(scn, bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530483
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530484 scn->qdf_dev = qdf_ctx;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530485 scn->hif_con_param = mode;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530486 qdf_atomic_init(&scn->active_tasklet_cnt);
487 qdf_atomic_init(&scn->link_suspended);
488 qdf_atomic_init(&scn->tasklet_from_intr);
Komal Seelam75080122016-03-02 15:18:25 +0530489 qdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_driver_state_callbacks));
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800490
491 status = hif_bus_open(scn, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530492 if (status != QDF_STATUS_SUCCESS) {
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800493 HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
494 __func__, status, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530495 qdf_mem_free(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530496 scn = NULL;
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800497 }
498
Komal Seelambd7c51d2016-02-24 10:27:30 +0530499 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800500}
501
502/**
503 * hif_close(): hif_close
504 * @hif_ctx: hif_ctx
505 *
506 * Return: n/a
507 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530508void hif_close(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800509{
Komal Seelam644263d2016-02-22 20:45:49 +0530510 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800511
512 if (scn == NULL) {
Komal Seelam5584a7c2016-02-24 19:22:48 +0530513 HIF_ERROR("%s: hif_opaque_softc is NULL", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800514 return;
515 }
516
517 if (scn->athdiag_procfs_inited) {
518 athdiag_procfs_remove();
519 scn->athdiag_procfs_inited = false;
520 }
521
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800522 hif_bus_close(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530523 qdf_mem_free(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800524}
525
526/**
527 * hif_enable(): hif_enable
528 * @hif_ctx: hif_ctx
529 * @dev: dev
530 * @bdev: bus dev
531 * @bid: bus ID
532 * @bus_type: bus type
533 * @type: enable type
534 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530535 * Return: QDF_STATUS
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800536 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530537QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800538 void *bdev, const hif_bus_id *bid,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530539 enum qdf_bus_type bus_type,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800540 enum hif_enable_type type)
541{
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530542 QDF_STATUS status;
Komal Seelam644263d2016-02-22 20:45:49 +0530543 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800544
545 if (scn == NULL) {
546 HIF_ERROR("%s: hif_ctx = NULL", __func__);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530547 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800548 }
549
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800550 status = hif_enable_bus(scn, dev, bdev, bid, type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530551 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800552 HIF_ERROR("%s: hif_enable_bus error = %d",
553 __func__, status);
554 return status;
555 }
556
557 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530558 hif_vote_link_up(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800559
Houston Hoffman108da402016-03-14 21:11:24 -0700560 if (hif_bus_configure(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800561 HIF_ERROR("%s: Target probe failed.", __func__);
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530562 hif_disable_bus(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530563 status = QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800564 return status;
565 }
Houston Hoffman108da402016-03-14 21:11:24 -0700566
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800567 /*
568 * Flag to avoid potential unallocated memory access from MSI
569 * interrupt handler which could get scheduled as soon as MSI
570 * is enabled, i.e to take care of the race due to the order
571 * in where MSI is enabled before the memory, that will be
572 * in interrupt handlers, is allocated.
573 */
574
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800575 scn->hif_init_done = true;
576
577 HIF_TRACE("%s: X OK", __func__);
578
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530579 return QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800580}
581
582/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800583 * hif_wlan_disable(): call the platform driver to disable wlan
Komal Seelambd7c51d2016-02-24 10:27:30 +0530584 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800585 *
586 * This function passes the con_mode to platform driver to disable
587 * wlan.
588 *
589 * Return: void
590 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530591void hif_wlan_disable(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800592{
593 enum icnss_driver_mode mode;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530594 uint32_t con_mode = hif_get_conparam(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800595
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530596 if (QDF_GLOBAL_FTM_MODE == con_mode)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800597 mode = ICNSS_FTM;
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700598 else if (QDF_IS_EPPING_ENABLED(con_mode))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800599 mode = ICNSS_EPPING;
Peng Xu7b962532015-10-02 17:17:03 -0700600 else
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800601 mode = ICNSS_MISSION;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800602
603 icnss_wlan_disable(mode);
604}
605
Komal Seelam5584a7c2016-02-24 19:22:48 +0530606void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800607{
Komal Seelam644263d2016-02-22 20:45:49 +0530608 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800609
610 if (!scn)
611 return;
612
613 hif_nointrs(scn);
614 if (scn->hif_init_done == false)
Komal Seelam644263d2016-02-22 20:45:49 +0530615 hif_shut_down_device(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800616 else
Komal Seelam644263d2016-02-22 20:45:49 +0530617 hif_stop(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800618
619 if (ADRASTEA_BU)
Komal Seelamf8600682016-02-02 18:17:13 +0530620 hif_vote_link_down(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800621
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530622 hif_disable_bus(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800623
Komal Seelambd7c51d2016-02-24 10:27:30 +0530624 hif_wlan_disable(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800625
626 scn->notice_send = false;
627
628 HIF_INFO("%s: X", __func__);
629}
630
631
632/**
Govind Singh2443fb32016-01-13 17:44:48 +0530633 * hif_crash_shutdown_dump_bus_register() - dump bus registers
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800634 * @hif_ctx: hif_ctx
635 *
636 * Return: n/a
637 */
638#if defined(TARGET_RAMDUMP_AFTER_KERNEL_PANIC) \
Houston Hoffmanbc693492016-03-14 21:11:41 -0700639&& defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800640
Govind Singh2443fb32016-01-13 17:44:48 +0530641static void hif_crash_shutdown_dump_bus_register(void *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800642{
Komal Seelam5584a7c2016-02-24 19:22:48 +0530643 struct hif_opaque_softc *scn = hif_ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800644
Govind Singh2443fb32016-01-13 17:44:48 +0530645 if (hif_check_soc_status(scn))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800646 return;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800647
Govind Singh2443fb32016-01-13 17:44:48 +0530648 if (hif_dump_registers(scn))
649 HIF_ERROR("Failed to dump bus registers!");
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800650}
651
652/**
653 * hif_crash_shutdown(): hif_crash_shutdown
654 *
655 * This function is called by the platform driver to dump CE registers
656 *
657 * @hif_ctx: hif_ctx
658 *
659 * Return: n/a
660 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530661void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800662{
Komal Seelam644263d2016-02-22 20:45:49 +0530663 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800664
Houston Hoffmanbc693492016-03-14 21:11:41 -0700665 if (!hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800666 return;
667
Houston Hoffmanbc693492016-03-14 21:11:41 -0700668 if (scn->bus_type == QDF_BUS_TYPE_SNOC) {
669 HIF_INFO_MED("%s: RAM dump disabled for bustype %d",
670 __func__, scn->bus_type);
671 return;
672 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800673
Komal Seelam6ee55902016-04-11 17:11:07 +0530674 if (TARGET_STATUS_RESET == scn->target_status) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800675 HIF_INFO_MED("%s: Target is already asserted, ignore!",
676 __func__);
677 return;
678 }
679
Komal Seelambd7c51d2016-02-24 10:27:30 +0530680 if (hif_is_load_or_unload_in_progress(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800681 HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
682 return;
683 }
684
Govind Singh2443fb32016-01-13 17:44:48 +0530685 hif_crash_shutdown_dump_bus_register(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800686
Komal Seelam644263d2016-02-22 20:45:49 +0530687 if (ol_copy_ramdump(hif_ctx))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800688 goto out;
689
690 HIF_INFO_MED("%s: RAM dump collecting completed!", __func__);
691
692out:
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800693 return;
694}
695#else
Komal Seelam5584a7c2016-02-24 19:22:48 +0530696void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800697{
698 HIF_INFO_MED("%s: Collecting target RAM dump disabled",
699 __func__);
700 return;
701}
702#endif /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
703
704#ifdef QCA_WIFI_3_0
705/**
706 * hif_check_fw_reg(): hif_check_fw_reg
707 * @scn: scn
708 * @state:
709 *
710 * Return: int
711 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530712int hif_check_fw_reg(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800713{
714 return 0;
715}
716#endif
717
718#ifdef IPA_OFFLOAD
719/**
720 * hif_read_phy_mem_base(): hif_read_phy_mem_base
721 * @scn: scn
722 * @phy_mem_base: physical mem base
723 *
724 * Return: n/a
725 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530726void hif_read_phy_mem_base(struct hif_softc *scn, qdf_dma_addr_t *phy_mem_base)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800727{
728 *phy_mem_base = scn->mem_pa;
729}
730#endif /* IPA_OFFLOAD */
731
732/**
733 * hif_get_device_type(): hif_get_device_type
734 * @device_id: device_id
735 * @revision_id: revision_id
736 * @hif_type: returned hif_type
737 * @target_type: returned target_type
738 *
739 * Return: int
740 */
741int hif_get_device_type(uint32_t device_id,
742 uint32_t revision_id,
743 uint32_t *hif_type, uint32_t *target_type)
744{
745 int ret = 0;
746
747 switch (device_id) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800748 case ADRASTEA_DEVICE_ID:
749 case ADRASTEA_DEVICE_ID_P2_E12:
750
751 *hif_type = HIF_TYPE_ADRASTEA;
752 *target_type = TARGET_TYPE_ADRASTEA;
753 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800754
755 case AR9888_DEVICE_ID:
756 *hif_type = HIF_TYPE_AR9888;
757 *target_type = TARGET_TYPE_AR9888;
758 break;
759
760 case AR6320_DEVICE_ID:
761 switch (revision_id) {
762 case AR6320_FW_1_1:
763 case AR6320_FW_1_3:
764 *hif_type = HIF_TYPE_AR6320;
765 *target_type = TARGET_TYPE_AR6320;
766 break;
767
768 case AR6320_FW_2_0:
769 case AR6320_FW_3_0:
770 case AR6320_FW_3_2:
771 *hif_type = HIF_TYPE_AR6320V2;
772 *target_type = TARGET_TYPE_AR6320V2;
773 break;
774
775 default:
776 HIF_ERROR("%s: error - dev_id = 0x%x, rev_id = 0x%x",
777 __func__, device_id, revision_id);
778 ret = -ENODEV;
779 goto end;
780 }
781 break;
782
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700783 case AR9887_DEVICE_ID:
784 *hif_type = HIF_TYPE_AR9888;
785 *target_type = TARGET_TYPE_AR9888;
786 HIF_INFO(" *********** AR9887 **************\n");
787 break;
788
789 case QCA9984_DEVICE_ID:
790 *hif_type = HIF_TYPE_QCA9984;
791 *target_type = TARGET_TYPE_QCA9984;
792 HIF_INFO(" *********** QCA9984 *************\n");
793 break;
794
795 case QCA9888_DEVICE_ID:
796 *hif_type = HIF_TYPE_QCA9888;
797 *target_type = TARGET_TYPE_QCA9888;
798 HIF_INFO(" *********** QCA9888 *************\n");
799 break;
800
801 case AR900B_DEVICE_ID:
802 *hif_type = HIF_TYPE_AR900B;
803 *target_type = TARGET_TYPE_AR900B;
804 HIF_INFO(" *********** AR900B *************\n");
805 break;
806
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800807 default:
808 HIF_ERROR("%s: Unsupported device ID!", __func__);
809 ret = -ENODEV;
810 break;
811 }
812end:
813 return ret;
814}
Komal Seelam91553ce2016-01-27 18:57:10 +0530815
816/**
Houston Hoffman26352592016-03-14 21:11:43 -0700817 * hif_needs_bmi() - return true if the soc needs bmi through the driver
818 * @hif_ctx: hif context
819 *
820 * Return: true if the soc needs driver bmi otherwise false
821 */
822bool hif_needs_bmi(struct hif_opaque_softc *hif_ctx)
823{
824 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx);
825 return hif_sc->bus_type != QDF_BUS_TYPE_SNOC;
826}
827
828/**
Houston Hoffman60a1eeb2016-03-14 21:11:44 -0700829 * hif_get_bus_type() - return the bus type
830 *
831 * Return: enum qdf_bus_type
832 */
833enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl)
834{
835 struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
836 return scn->bus_type;
837}
838
839/**
Komal Seelam91553ce2016-01-27 18:57:10 +0530840 * Target info and ini parameters are global to the driver
841 * Hence these structures are exposed to all the modules in
842 * the driver and they don't need to maintains multiple copies
843 * of the same info, instead get the handle from hif and
844 * modify them in hif
845 */
846
847/**
848 * hif_get_ini_handle() - API to get hif_config_param handle
Komal Seelam644263d2016-02-22 20:45:49 +0530849 * @hif_ctx: HIF Context
Komal Seelam91553ce2016-01-27 18:57:10 +0530850 *
851 * Return: pointer to hif_config_info
852 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530853struct hif_config_info *hif_get_ini_handle(struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530854{
Komal Seelam644263d2016-02-22 20:45:49 +0530855 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
856
857 return &sc->hif_config;
Komal Seelam91553ce2016-01-27 18:57:10 +0530858}
859
860/**
861 * hif_get_target_info_handle() - API to get hif_target_info handle
Komal Seelam644263d2016-02-22 20:45:49 +0530862 * @hif_ctx: HIF context
Komal Seelam91553ce2016-01-27 18:57:10 +0530863 *
864 * Return: Pointer to hif_target_info
865 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530866struct hif_target_info *hif_get_target_info_handle(
867 struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530868{
Komal Seelam644263d2016-02-22 20:45:49 +0530869 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
870
871 return &sc->target_info;
872
Komal Seelam91553ce2016-01-27 18:57:10 +0530873}
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530874
875#if defined(FEATURE_LRO)
876/**
877 * hif_lro_flush_cb_register - API to register for LRO Flush Callback
878 * @scn: HIF Context
879 * @handler: Function pointer to be called by HIF
880 * @data: Private data to be used by the module registering to HIF
881 *
882 * Return: void
883 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530884void hif_lro_flush_cb_register(struct hif_opaque_softc *scn,
885 void (handler)(void *), void *data)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530886{
887 ce_lro_flush_cb_register(scn, handler, data);
888}
889
890/**
891 * hif_lro_flush_cb_deregister - API to deregister for LRO Flush Callbacks
892 * @scn: HIF Context
893 *
894 * Return: void
895 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530896void hif_lro_flush_cb_deregister(struct hif_opaque_softc *scn)
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530897{
898 ce_lro_flush_cb_deregister(scn);
899}
900#endif
Komal Seelam644263d2016-02-22 20:45:49 +0530901
902/**
903 * hif_get_target_status - API to get target status
904 * @hif_ctx: HIF Context
905 *
Komal Seelam6ee55902016-04-11 17:11:07 +0530906 * Return: enum hif_target_status
Komal Seelam644263d2016-02-22 20:45:49 +0530907 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530908enum hif_target_status hif_get_target_status(struct hif_opaque_softc *hif_ctx)
Komal Seelam644263d2016-02-22 20:45:49 +0530909{
910 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
911
912 return scn->target_status;
913}
914
915/**
Komal Seelama5911d32016-02-24 19:21:59 +0530916 * hif_set_target_status() - API to set target status
Komal Seelam644263d2016-02-22 20:45:49 +0530917 * @hif_ctx: HIF Context
918 * @status: Target Status
919 *
920 * Return: void
921 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530922void hif_set_target_status(struct hif_opaque_softc *hif_ctx, enum
923 hif_target_status status)
Komal Seelam644263d2016-02-22 20:45:49 +0530924{
925 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
926
927 scn->target_status = status;
928}
Komal Seelama5911d32016-02-24 19:21:59 +0530929
930/**
931 * hif_init_ini_config() - API to initialize HIF configuration parameters
932 * @hif_ctx: HIF Context
933 * @cfg: HIF Configuration
934 *
935 * Return: void
936 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530937void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
938 struct hif_config_info *cfg)
Komal Seelama5911d32016-02-24 19:21:59 +0530939{
940 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
941
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530942 qdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
Komal Seelama5911d32016-02-24 19:21:59 +0530943}
Komal Seelambd7c51d2016-02-24 10:27:30 +0530944
945/**
946 * hif_get_conparam() - API to get driver mode in HIF
947 * @scn: HIF Context
948 *
949 * Return: driver mode of operation
950 */
951uint32_t hif_get_conparam(struct hif_softc *scn)
952{
953 if (!scn)
954 return 0;
955
956 return scn->hif_con_param;
957}
958
959/**
960 * hif_get_callbacks_handle() - API to get callbacks Handle
961 * @scn: HIF Context
962 *
963 * Return: pointer to HIF Callbacks
964 */
Komal Seelam75080122016-03-02 15:18:25 +0530965struct hif_driver_state_callbacks *hif_get_callbacks_handle(struct hif_softc *scn)
Komal Seelambd7c51d2016-02-24 10:27:30 +0530966{
967 return &scn->callbacks;
968}
969
970/**
971 * hif_is_driver_unloading() - API to query upper layers if driver is unloading
972 * @scn: HIF Context
973 *
974 * Return: True/False
975 */
976bool hif_is_driver_unloading(struct hif_softc *scn)
977{
Komal Seelam75080122016-03-02 15:18:25 +0530978 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530979
980 if (cbk && cbk->is_driver_unloading)
981 return cbk->is_driver_unloading(cbk->context);
982
983 return false;
984}
985
986/**
987 * hif_is_load_or_unload_in_progress() - API to query upper layers if
988 * load/unload in progress
989 * @scn: HIF Context
990 *
991 * Return: True/False
992 */
993bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
994{
Komal Seelam75080122016-03-02 15:18:25 +0530995 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530996
997 if (cbk && cbk->is_load_unload_in_progress)
998 return cbk->is_load_unload_in_progress(cbk->context);
999
1000 return false;
1001}
1002
1003/**
1004 * hif_is_recovery_in_progress() - API to query upper layers if recovery in
1005 * progress
1006 * @scn: HIF Context
1007 *
1008 * Return: True/False
1009 */
1010bool hif_is_recovery_in_progress(struct hif_softc *scn)
1011{
Komal Seelam75080122016-03-02 15:18:25 +05301012 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +05301013
1014 if (cbk && cbk->is_recovery_in_progress)
1015 return cbk->is_recovery_in_progress(cbk->context);
1016
1017 return false;
1018}
Houston Hoffman56e0d702016-05-05 17:48:06 -07001019
1020/**
1021 * hif_batch_send() - API to access hif specific function
1022 * ce_batch_send.
1023 * @osc: HIF Context
1024 * @msdu : list of msdus to be sent
1025 * @transfer_id : transfer id
1026 * @len : donwloaded length
1027 *
1028 * Return: list of msds not sent
1029 */
1030qdf_nbuf_t hif_batch_send(struct hif_opaque_softc *osc, qdf_nbuf_t msdu,
1031 uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
1032{
1033 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1034 return ce_batch_send((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
1035 len, sendhead);
1036}
1037
1038/**
1039 * hif_update_tx_ring() - API to access hif specific function
1040 * ce_update_tx_ring.
1041 * @osc: HIF Context
1042 * @num_htt_cmpls : number of htt compl received.
1043 *
1044 * Return: void
1045 */
1046void hif_update_tx_ring(struct hif_opaque_softc *osc, u_int32_t num_htt_cmpls)
1047{
1048 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1049 ce_update_tx_ring(ce_tx_hdl, num_htt_cmpls);
1050}
1051
1052
1053/**
1054 * hif_send_single() - API to access hif specific function
1055 * ce_send_single.
1056 * @osc: HIF Context
1057 * @msdu : msdu to be sent
1058 * @transfer_id: transfer id
1059 * @len : downloaded length
1060 *
1061 * Return: msdu sent status
1062 */
1063int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
1064 transfer_id, u_int32_t len)
1065{
1066 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1067 return ce_send_single((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
1068 len);
1069}
1070
1071/**
1072 * hif_send_fast() - API to access hif specific function
1073 * ce_send_fast.
1074 * @osc: HIF Context
1075 * @msdu : array of msdus to be sent
1076 * @num_msdus : number of msdus in an array
1077 * @transfer_id: transfer id
1078 *
1079 * Return: No. of packets that could be sent
1080 */
1081int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t *nbuf_arr,
1082 uint32_t num_msdus, uint32_t transfer_id)
1083{
1084 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
1085 return ce_send_fast((struct CE_handle *)ce_tx_hdl, nbuf_arr, num_msdus,
1086 transfer_id);
1087}
1088
1089/**
1090 * hif_pkt_dl_len_set() - API to access hif specific function
1091 * ce_pkt_dl_len_set.
1092 * @osc: HIF Context
1093 * @pkt_download_len: download length
1094 *
1095 * Return: None
1096 */
1097void hif_pkt_dl_len_set(void *hif_sc, unsigned int pkt_download_len)
1098{
1099 ce_pkt_dl_len_set(hif_sc, pkt_download_len);
1100}
1101
1102/**
1103 * hif_reg_write() - API to access hif specific function
1104 * hif_write32_mb.
1105 * @hif_ctx : HIF Context
1106 * @offset : offset on which value has to be written
1107 * @value : value to be written
1108 *
1109 * Return: None
1110 */
1111void hif_reg_write(struct hif_opaque_softc *hif_ctx, uint32_t offset,
1112 uint32_t value)
1113{
1114 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
1115 hif_write32_mb(scn->mem + offset, value);
1116
1117}
1118
1119/**
1120 * hif_reg_read() - API to access hif specific function
1121 * hif_read32_mb.
1122 * @hif_ctx : HIF Context
1123 * @offset : offset from which value has to be read
1124 *
1125 * Return: Read value
1126 */
1127uint32_t hif_reg_read(struct hif_opaque_softc *hif_ctx, uint32_t offset)
1128{
1129
1130 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
1131 return hif_read32_mb(scn->mem + offset);
1132}