blob: bafdc4e3f868f0feb87c1995415c35dc4237c28a [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Pratik Gandhi034cb7c2017-11-10 16:46:06 +05302 * Copyright (c) 2015-2018 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>
Pratik Gandhi034cb7c2017-11-10 16:46:06 +053036#include <target_type.h>
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080037#include "regtable.h"
38#define ATH_MODULE_NAME hif
39#include <a_debug.h>
40#include "hif_main.h"
41#include "hif_hw_version.h"
Poddar, Siddarthe41943f2016-04-27 15:33:48 +053042#if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080043#include "ce_tasklet.h"
tfyu6c7625b2017-08-10 16:20:32 +080044#include "ce_api.h"
Poddar, Siddarthe41943f2016-04-27 15:33:48 +053045#endif
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053046#include "qdf_trace.h"
47#include "qdf_status.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080048#include "hif_debug.h"
49#include "mp_dev.h"
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +053050#ifdef QCA_WIFI_QCA8074
51#include "hal_api.h"
52#endif
Manjunathappa Prakash2146da32016-10-13 14:47:47 -070053#include "hif_napi.h"
Dustin Brownccf859d2017-06-01 14:31:01 -070054#include "hif_unit_test_suspend_i.h"
Pratik Gandhidc82a772018-01-30 18:57:05 +053055#include "qdf_module.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080056
Komal Seelam5584a7c2016-02-24 19:22:48 +053057void hif_dump(struct hif_opaque_softc *hif_ctx, uint8_t cmd_id, bool start)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080058{
Poddar, Siddarthe41943f2016-04-27 15:33:48 +053059 hif_trigger_dump(hif_ctx, cmd_id, start);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080060}
61
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080062/**
63 * hif_get_target_id(): hif_get_target_id
64 *
65 * Return the virtual memory base address to the caller
66 *
Komal Seelam644263d2016-02-22 20:45:49 +053067 * @scn: hif_softc
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080068 *
69 * Return: A_target_id_t
70 */
Komal Seelam644263d2016-02-22 20:45:49 +053071A_target_id_t hif_get_target_id(struct hif_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080072{
73 return scn->mem;
74}
75
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080076/**
77 * hif_get_targetdef(): hif_get_targetdef
78 * @scn: scn
79 *
80 * Return: void *
81 */
Komal Seelam5584a7c2016-02-24 19:22:48 +053082void *hif_get_targetdef(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080083{
Komal Seelam644263d2016-02-22 20:45:49 +053084 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
85
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080086 return scn->targetdef;
87}
88
89/**
90 * hif_vote_link_down(): unvote for link up
91 *
92 * Call hif_vote_link_down to release a previous request made using
93 * hif_vote_link_up. A hif_vote_link_down call should only be made
94 * after a corresponding hif_vote_link_up, otherwise you could be
95 * negating a vote from another source. When no votes are present
96 * hif will not guarantee the linkstate after hif_bus_suspend.
97 *
98 * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
99 * and initialization deinitialization sequencences.
100 *
101 * Return: n/a
102 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530103void hif_vote_link_down(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800104{
Komal Seelam644263d2016-02-22 20:45:49 +0530105 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800106
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700107 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800108 scn->linkstate_vote--;
109 if (scn->linkstate_vote == 0)
Houston Hoffmancceec342015-11-11 11:37:20 -0800110 hif_bus_prevent_linkdown(scn, false);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800111}
112
113/**
114 * hif_vote_link_up(): vote to prevent bus from suspending
115 *
116 * Makes hif guarantee that fw can message the host normally
117 * durring suspend.
118 *
119 * SYNCHRONIZE WITH hif_vote_link_up by only calling in MC thread
120 * and initialization deinitialization sequencences.
121 *
122 * Return: n/a
123 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530124void hif_vote_link_up(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800125{
Komal Seelam644263d2016-02-22 20:45:49 +0530126 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800127
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700128 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800129 scn->linkstate_vote++;
130 if (scn->linkstate_vote == 1)
Houston Hoffmancceec342015-11-11 11:37:20 -0800131 hif_bus_prevent_linkdown(scn, true);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800132}
133
134/**
135 * hif_can_suspend_link(): query if hif is permitted to suspend the link
136 *
137 * Hif will ensure that the link won't be suspended if the upperlayers
138 * don't want it to.
139 *
140 * SYNCHRONIZATION: MC thread is stopped before bus suspend thus
141 * we don't need extra locking to ensure votes dont change while
142 * we are in the process of suspending or resuming.
143 *
144 * Return: false if hif will guarantee link up durring suspend.
145 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530146bool hif_can_suspend_link(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800147{
Komal Seelam644263d2016-02-22 20:45:49 +0530148 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800149
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700150 QDF_BUG(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800151 return scn->linkstate_vote == 0;
152}
153
154/**
155 * hif_hia_item_address(): hif_hia_item_address
156 * @target_type: target_type
157 * @item_offset: item_offset
158 *
159 * Return: n/a
160 */
161uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
162{
163 switch (target_type) {
164 case TARGET_TYPE_AR6002:
165 return AR6002_HOST_INTEREST_ADDRESS + item_offset;
166 case TARGET_TYPE_AR6003:
167 return AR6003_HOST_INTEREST_ADDRESS + item_offset;
168 case TARGET_TYPE_AR6004:
169 return AR6004_HOST_INTEREST_ADDRESS + item_offset;
170 case TARGET_TYPE_AR6006:
171 return AR6006_HOST_INTEREST_ADDRESS + item_offset;
172 case TARGET_TYPE_AR9888:
173 return AR9888_HOST_INTEREST_ADDRESS + item_offset;
174 case TARGET_TYPE_AR6320:
175 case TARGET_TYPE_AR6320V2:
176 return AR6320_HOST_INTEREST_ADDRESS + item_offset;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800177 case TARGET_TYPE_ADRASTEA:
178 /* ADRASTEA doesn't have a host interest address */
179 ASSERT(0);
180 return 0;
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700181 case TARGET_TYPE_AR900B:
182 return AR900B_HOST_INTEREST_ADDRESS + item_offset;
183 case TARGET_TYPE_QCA9984:
184 return QCA9984_HOST_INTEREST_ADDRESS + item_offset;
185 case TARGET_TYPE_QCA9888:
186 return QCA9888_HOST_INTEREST_ADDRESS + item_offset;
187 case TARGET_TYPE_IPQ4019:
188 return IPQ4019_HOST_INTEREST_ADDRESS + item_offset;
189
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800190 default:
191 ASSERT(0);
192 return 0;
193 }
194}
195
196/**
197 * hif_max_num_receives_reached() - check max receive is reached
Komal Seelambd7c51d2016-02-24 10:27:30 +0530198 * @scn: HIF Context
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800199 * @count: unsigned int.
200 *
201 * Output check status as bool
202 *
203 * Return: bool
204 */
Komal Seelambd7c51d2016-02-24 10:27:30 +0530205bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800206{
Houston Hoffman75ef5a52016-04-14 17:15:49 -0700207 if (QDF_IS_EPPING_ENABLED(hif_get_conparam(scn)))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800208 return count > 120;
209 else
210 return count > MAX_NUM_OF_RECEIVES;
211}
212
213/**
214 * init_buffer_count() - initial buffer count
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530215 * @maxSize: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800216 *
217 * routine to modify the initial buffer count to be allocated on an os
218 * platform basis. Platform owner will need to modify this as needed
219 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530220 * Return: qdf_size_t
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800221 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530222qdf_size_t init_buffer_count(qdf_size_t maxSize)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800223{
224 return maxSize;
225}
226
227/**
Nirav Shahd7f91592016-04-21 14:18:43 +0530228 * hif_save_htc_htt_config_endpoint() - save htt_tx_endpoint
229 * @hif_ctx: hif context
230 * @htc_htt_tx_endpoint: htt_tx_endpoint
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800231 *
232 * Return: void
233 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530234void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
Nirav Shahd7f91592016-04-21 14:18:43 +0530235 int htc_htt_tx_endpoint)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800236{
Komal Seelam644263d2016-02-22 20:45:49 +0530237 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800238
239 if (!scn) {
240 HIF_ERROR("%s: error: scn or scn->hif_sc is NULL!",
241 __func__);
242 return;
243 }
244
Nirav Shahd7f91592016-04-21 14:18:43 +0530245 scn->htc_htt_tx_endpoint = htc_htt_tx_endpoint;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800246}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530247qdf_export_symbol(hif_save_htc_htt_config_endpoint);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800248
Houston Hoffmanec93ab02016-05-03 20:09:55 -0700249static const struct qwlan_hw qwlan_hw_list[] = {
250 {
251 .id = AR6320_REV1_VERSION,
252 .subid = 0,
253 .name = "QCA6174_REV1",
254 },
255 {
256 .id = AR6320_REV1_1_VERSION,
257 .subid = 0x1,
258 .name = "QCA6174_REV1_1",
259 },
260 {
261 .id = AR6320_REV1_3_VERSION,
262 .subid = 0x2,
263 .name = "QCA6174_REV1_3",
264 },
265 {
266 .id = AR6320_REV2_1_VERSION,
267 .subid = 0x4,
268 .name = "QCA6174_REV2_1",
269 },
270 {
271 .id = AR6320_REV2_1_VERSION,
272 .subid = 0x5,
273 .name = "QCA6174_REV2_2",
274 },
275 {
276 .id = AR6320_REV3_VERSION,
277 .subid = 0x6,
278 .name = "QCA6174_REV2.3",
279 },
280 {
281 .id = AR6320_REV3_VERSION,
282 .subid = 0x8,
283 .name = "QCA6174_REV3",
284 },
285 {
286 .id = AR6320_REV3_VERSION,
287 .subid = 0x9,
288 .name = "QCA6174_REV3_1",
289 },
290 {
291 .id = AR6320_REV3_2_VERSION,
292 .subid = 0xA,
293 .name = "AR6320_REV3_2_VERSION",
Houston Hoffmancd0884a2016-08-24 15:30:09 -0700294 },
295 {
296 .id = WCN3990_v1,
297 .subid = 0x0,
298 .name = "WCN3990_V1",
Houston Hoffmandd4da482016-10-17 12:41:45 -0700299 },
300 {
301 .id = WCN3990_v2,
302 .subid = 0x0,
303 .name = "WCN3990_V2",
Houston Hoffman59fd2452016-11-19 17:27:10 -0800304 },
305 {
306 .id = WCN3990_v2_1,
307 .subid = 0x0,
308 .name = "WCN3990_V2.1",
Yingying Tangd8921742016-10-18 18:13:07 +0800309 },
310 {
311 .id = QCA9379_REV1_VERSION,
312 .subid = 0xC,
313 .name = "QCA9379_REV1",
Yingying Tang80404362016-10-20 23:29:57 +0800314 },
315 {
316 .id = QCA9379_REV1_VERSION,
317 .subid = 0xD,
318 .name = "QCA9379_REV1_1",
Houston Hoffmanec93ab02016-05-03 20:09:55 -0700319 }
320};
321
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800322/**
323 * hif_get_hw_name(): get a human readable name for the hardware
Komal Seelam91553ce2016-01-27 18:57:10 +0530324 * @info: Target Info
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800325 *
Komal Seelam91553ce2016-01-27 18:57:10 +0530326 * Return: human readable name for the underlying wifi hardware.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800327 */
Komal Seelam91553ce2016-01-27 18:57:10 +0530328static const char *hif_get_hw_name(struct hif_target_info *info)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800329{
330 int i;
Komal Seelam91553ce2016-01-27 18:57:10 +0530331
Houston Hoffman60af6752016-11-21 12:13:36 -0800332 if (info->hw_name)
333 return info->hw_name;
334
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800335 for (i = 0; i < ARRAY_SIZE(qwlan_hw_list); i++) {
Komal Seelam91553ce2016-01-27 18:57:10 +0530336 if (info->target_version == qwlan_hw_list[i].id &&
337 info->target_revision == qwlan_hw_list[i].subid) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800338 return qwlan_hw_list[i].name;
339 }
340 }
341
Houston Hoffman60af6752016-11-21 12:13:36 -0800342 info->hw_name = qdf_mem_malloc(64);
343 if (!info->hw_name)
344 return "Unknown Device (nomem)";
345
346 i = qdf_snprint(info->hw_name, 64, "HW_VERSION=%x.",
347 info->target_version);
348 if (i < 0)
349 return "Unknown Device (snprintf failure)";
350 else
351 return info->hw_name;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800352}
353
354/**
355 * hif_get_hw_info(): hif_get_hw_info
356 * @scn: scn
357 * @version: version
358 * @revision: revision
359 *
360 * Return: n/a
361 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530362void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800363 const char **target_name)
364{
Komal Seelam91553ce2016-01-27 18:57:10 +0530365 struct hif_target_info *info = hif_get_target_info_handle(scn);
Mohit Khanna440c5292016-05-12 11:05:06 -0700366 struct hif_softc *sc = HIF_GET_SOFTC(scn);
367
368 if (sc->bus_type == QDF_BUS_TYPE_USB)
369 hif_usb_get_hw_info(sc);
370
Komal Seelam91553ce2016-01-27 18:57:10 +0530371 *version = info->target_version;
372 *revision = info->target_revision;
373 *target_name = hif_get_hw_name(info);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800374}
375
376/**
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530377 * hif_get_dev_ba(): API to get device base address.
378 * @scn: scn
379 * @version: version
380 * @revision: revision
381 *
382 * Return: n/a
383 */
384void *hif_get_dev_ba(struct hif_opaque_softc *hif_handle)
385{
386 struct hif_softc *scn = (struct hif_softc *)hif_handle;
387
388 return scn->mem;
389}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530390qdf_export_symbol(hif_get_dev_ba);
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530391/**
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800392 * hif_open(): hif_open
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530393 * @qdf_ctx: QDF Context
Komal Seelambd7c51d2016-02-24 10:27:30 +0530394 * @mode: Driver Mode
395 * @bus_type: Bus Type
396 * @cbk: CDS Callbacks
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800397 *
Komal Seelambd7c51d2016-02-24 10:27:30 +0530398 * API to open HIF Context
399 *
400 * Return: HIF Opaque Pointer
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800401 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530402struct hif_opaque_softc *hif_open(qdf_device_t qdf_ctx, uint32_t mode,
403 enum qdf_bus_type bus_type,
Komal Seelam75080122016-03-02 15:18:25 +0530404 struct hif_driver_state_callbacks *cbk)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800405{
Komal Seelam644263d2016-02-22 20:45:49 +0530406 struct hif_softc *scn;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530407 QDF_STATUS status = QDF_STATUS_SUCCESS;
Houston Hoffman162164c2016-03-14 21:12:10 -0700408 int bus_context_size = hif_bus_get_context_size(bus_type);
409
410 if (bus_context_size == 0) {
411 HIF_ERROR("%s: context size 0 not allowed", __func__);
412 return NULL;
413 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800414
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530415 scn = (struct hif_softc *)qdf_mem_malloc(bus_context_size);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530416 if (!scn) {
417 HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
418 __func__, bus_context_size);
419 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800420 }
421
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530422 scn->qdf_dev = qdf_ctx;
Komal Seelambd7c51d2016-02-24 10:27:30 +0530423 scn->hif_con_param = mode;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530424 qdf_atomic_init(&scn->active_tasklet_cnt);
Venkateswara Swamy Bandaru31108f32016-08-08 18:04:29 +0530425 qdf_atomic_init(&scn->active_grp_tasklet_cnt);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530426 qdf_atomic_init(&scn->link_suspended);
427 qdf_atomic_init(&scn->tasklet_from_intr);
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700428 qdf_mem_copy(&scn->callbacks, cbk,
429 sizeof(struct hif_driver_state_callbacks));
Houston Hoffman3db96a42016-05-05 19:54:39 -0700430 scn->bus_type = bus_type;
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800431 status = hif_bus_open(scn, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530432 if (status != QDF_STATUS_SUCCESS) {
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800433 HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
434 __func__, status, bus_type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530435 qdf_mem_free(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +0530436 scn = NULL;
Houston Hoffman3cfe6862016-01-08 10:33:55 -0800437 }
438
Komal Seelambd7c51d2016-02-24 10:27:30 +0530439 return GET_HIF_OPAQUE_HDL(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800440}
441
442/**
443 * hif_close(): hif_close
444 * @hif_ctx: hif_ctx
445 *
446 * Return: n/a
447 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530448void hif_close(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800449{
Komal Seelam644263d2016-02-22 20:45:49 +0530450 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800451
452 if (scn == NULL) {
Komal Seelam5584a7c2016-02-24 19:22:48 +0530453 HIF_ERROR("%s: hif_opaque_softc is NULL", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800454 return;
455 }
456
457 if (scn->athdiag_procfs_inited) {
458 athdiag_procfs_remove();
459 scn->athdiag_procfs_inited = false;
460 }
461
Houston Hoffman60af6752016-11-21 12:13:36 -0800462 if (scn->target_info.hw_name) {
463 char *hw_name = scn->target_info.hw_name;
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700464
Houston Hoffman60af6752016-11-21 12:13:36 -0800465 scn->target_info.hw_name = "ErrUnloading";
466 qdf_mem_free(hw_name);
467 }
468
Arunk Khandavallie14e8e92017-04-03 21:40:26 +0530469 if (scn->vaddr_rri_on_ddr)
470 qdf_mem_free_consistent(scn->qdf_dev, scn->qdf_dev->dev,
471 (CE_COUNT*sizeof(uint32_t)),
472 scn->vaddr_rri_on_ddr, scn->paddr_rri_on_ddr,
473 0);
474
475 scn->vaddr_rri_on_ddr = NULL;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800476 hif_bus_close(scn);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530477 qdf_mem_free(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800478}
479
Houston Hoffman6fe60592016-11-18 13:12:08 -0800480#ifdef QCA_WIFI_QCA8074
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530481static QDF_STATUS hif_hal_attach(struct hif_softc *scn)
482{
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530483 if (ce_srng_based(scn)) {
484 scn->hal_soc = hal_attach(scn, scn->qdf_dev);
485 if (scn->hal_soc == NULL)
486 return QDF_STATUS_E_FAILURE;
487 }
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530488
489 return QDF_STATUS_SUCCESS;
490}
Houston Hoffman4e2df402017-05-21 19:36:56 -0700491
492static QDF_STATUS hif_hal_detach(struct hif_softc *scn)
493{
494 if (ce_srng_based(scn)) {
495 hal_detach(scn->hal_soc);
496 scn->hal_soc = NULL;
497 }
498
499 return QDF_STATUS_SUCCESS;
500}
Houston Hoffman6fe60592016-11-18 13:12:08 -0800501#else
502static QDF_STATUS hif_hal_attach(struct hif_softc *scn)
503{
504 return QDF_STATUS_SUCCESS;
505}
Houston Hoffman4e2df402017-05-21 19:36:56 -0700506
507static QDF_STATUS hif_hal_detach(struct hif_softc *scn)
508{
509 return QDF_STATUS_SUCCESS;
510}
Houston Hoffman6fe60592016-11-18 13:12:08 -0800511#endif
512
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800513/**
514 * hif_enable(): hif_enable
515 * @hif_ctx: hif_ctx
516 * @dev: dev
517 * @bdev: bus dev
518 * @bid: bus ID
519 * @bus_type: bus type
520 * @type: enable type
521 *
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530522 * Return: QDF_STATUS
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800523 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530524QDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700525 void *bdev,
526 const struct hif_bus_id *bid,
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530527 enum qdf_bus_type bus_type,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800528 enum hif_enable_type type)
529{
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530530 QDF_STATUS status;
Komal Seelam644263d2016-02-22 20:45:49 +0530531 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800532
533 if (scn == NULL) {
534 HIF_ERROR("%s: hif_ctx = NULL", __func__);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530535 return QDF_STATUS_E_NULL_VALUE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800536 }
537
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800538 status = hif_enable_bus(scn, dev, bdev, bid, type);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530539 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800540 HIF_ERROR("%s: hif_enable_bus error = %d",
541 __func__, status);
542 return status;
543 }
544
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530545 status = hif_hal_attach(scn);
546 if (status != QDF_STATUS_SUCCESS) {
547 HIF_ERROR("%s: hal attach failed", __func__);
Houston Hoffman4e2df402017-05-21 19:36:56 -0700548 goto disable_bus;
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +0530549 }
550
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__);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530553 status = QDF_STATUS_E_FAILURE;
Houston Hoffman4e2df402017-05-21 19:36:56 -0700554 goto hal_detach;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800555 }
Houston Hoffman108da402016-03-14 21:11:24 -0700556
Dustin Brownccf859d2017-06-01 14:31:01 -0700557 hif_ut_suspend_init(scn);
558
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800559 /*
560 * Flag to avoid potential unallocated memory access from MSI
561 * interrupt handler which could get scheduled as soon as MSI
562 * is enabled, i.e to take care of the race due to the order
563 * in where MSI is enabled before the memory, that will be
564 * in interrupt handlers, is allocated.
565 */
566
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800567 scn->hif_init_done = true;
568
Srinivas Girigowda6e0cfd92017-03-09 15:49:59 -0800569 HIF_DBG("%s: OK", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800570
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530571 return QDF_STATUS_SUCCESS;
Houston Hoffman4e2df402017-05-21 19:36:56 -0700572
573hal_detach:
574 hif_hal_detach(scn);
575disable_bus:
576 hif_disable_bus(scn);
577 return status;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800578}
579
Komal Seelam5584a7c2016-02-24 19:22:48 +0530580void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800581{
Komal Seelam644263d2016-02-22 20:45:49 +0530582 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800583
584 if (!scn)
585 return;
586
587 hif_nointrs(scn);
588 if (scn->hif_init_done == false)
Poddar, Siddarthe41943f2016-04-27 15:33:48 +0530589 hif_shutdown_device(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800590 else
Komal Seelam644263d2016-02-22 20:45:49 +0530591 hif_stop(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800592
Houston Hoffman4e2df402017-05-21 19:36:56 -0700593 hif_hal_detach(scn);
594
Vishwajith Upendra3f78aa62016-02-09 17:53:02 +0530595 hif_disable_bus(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800596
Komal Seelambd7c51d2016-02-24 10:27:30 +0530597 hif_wlan_disable(scn);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800598
599 scn->notice_send = false;
600
Srinivas Girigowda6e0cfd92017-03-09 15:49:59 -0800601 HIF_DBG("%s: X", __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800602}
603
Nirav Shahb70bd732016-05-25 14:31:51 +0530604void hif_display_stats(struct hif_opaque_softc *hif_ctx)
605{
606 hif_display_bus_stats(hif_ctx);
607}
608
609void hif_clear_stats(struct hif_opaque_softc *hif_ctx)
610{
611 hif_clear_bus_stats(hif_ctx);
612}
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800613
614/**
Govind Singh2443fb32016-01-13 17:44:48 +0530615 * hif_crash_shutdown_dump_bus_register() - dump bus registers
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800616 * @hif_ctx: hif_ctx
617 *
618 * Return: n/a
619 */
620#if defined(TARGET_RAMDUMP_AFTER_KERNEL_PANIC) \
Houston Hoffmanbc693492016-03-14 21:11:41 -0700621&& defined(DEBUG)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800622
Govind Singh2443fb32016-01-13 17:44:48 +0530623static void hif_crash_shutdown_dump_bus_register(void *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800624{
Komal Seelam5584a7c2016-02-24 19:22:48 +0530625 struct hif_opaque_softc *scn = hif_ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800626
Govind Singh2443fb32016-01-13 17:44:48 +0530627 if (hif_check_soc_status(scn))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800628 return;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800629
Govind Singh2443fb32016-01-13 17:44:48 +0530630 if (hif_dump_registers(scn))
631 HIF_ERROR("Failed to dump bus registers!");
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800632}
633
634/**
635 * hif_crash_shutdown(): hif_crash_shutdown
636 *
637 * This function is called by the platform driver to dump CE registers
638 *
639 * @hif_ctx: hif_ctx
640 *
641 * Return: n/a
642 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530643void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800644{
Komal Seelam644263d2016-02-22 20:45:49 +0530645 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800646
Houston Hoffmanbc693492016-03-14 21:11:41 -0700647 if (!hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800648 return;
649
Houston Hoffmanbc693492016-03-14 21:11:41 -0700650 if (scn->bus_type == QDF_BUS_TYPE_SNOC) {
651 HIF_INFO_MED("%s: RAM dump disabled for bustype %d",
652 __func__, scn->bus_type);
653 return;
654 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800655
Komal Seelam6ee55902016-04-11 17:11:07 +0530656 if (TARGET_STATUS_RESET == scn->target_status) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800657 HIF_INFO_MED("%s: Target is already asserted, ignore!",
658 __func__);
659 return;
660 }
661
Komal Seelambd7c51d2016-02-24 10:27:30 +0530662 if (hif_is_load_or_unload_in_progress(scn)) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800663 HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
664 return;
665 }
666
Govind Singh2443fb32016-01-13 17:44:48 +0530667 hif_crash_shutdown_dump_bus_register(hif_ctx);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800668
Komal Seelam644263d2016-02-22 20:45:49 +0530669 if (ol_copy_ramdump(hif_ctx))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800670 goto out;
671
672 HIF_INFO_MED("%s: RAM dump collecting completed!", __func__);
673
674out:
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800675 return;
676}
677#else
Komal Seelam5584a7c2016-02-24 19:22:48 +0530678void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800679{
680 HIF_INFO_MED("%s: Collecting target RAM dump disabled",
681 __func__);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800682}
683#endif /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */
684
685#ifdef QCA_WIFI_3_0
686/**
687 * hif_check_fw_reg(): hif_check_fw_reg
688 * @scn: scn
689 * @state:
690 *
691 * Return: int
692 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530693int hif_check_fw_reg(struct hif_opaque_softc *scn)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800694{
695 return 0;
696}
697#endif
698
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800699/**
700 * hif_read_phy_mem_base(): hif_read_phy_mem_base
701 * @scn: scn
702 * @phy_mem_base: physical mem base
703 *
704 * Return: n/a
705 */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530706void hif_read_phy_mem_base(struct hif_softc *scn, qdf_dma_addr_t *phy_mem_base)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800707{
708 *phy_mem_base = scn->mem_pa;
709}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530710qdf_export_symbol(hif_read_phy_mem_base);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800711
712/**
713 * hif_get_device_type(): hif_get_device_type
714 * @device_id: device_id
715 * @revision_id: revision_id
716 * @hif_type: returned hif_type
717 * @target_type: returned target_type
718 *
719 * Return: int
720 */
721int hif_get_device_type(uint32_t device_id,
722 uint32_t revision_id,
723 uint32_t *hif_type, uint32_t *target_type)
724{
725 int ret = 0;
726
727 switch (device_id) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800728 case ADRASTEA_DEVICE_ID_P2_E12:
729
730 *hif_type = HIF_TYPE_ADRASTEA;
731 *target_type = TARGET_TYPE_ADRASTEA;
732 break;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800733
734 case AR9888_DEVICE_ID:
735 *hif_type = HIF_TYPE_AR9888;
736 *target_type = TARGET_TYPE_AR9888;
737 break;
738
739 case AR6320_DEVICE_ID:
740 switch (revision_id) {
741 case AR6320_FW_1_1:
742 case AR6320_FW_1_3:
743 *hif_type = HIF_TYPE_AR6320;
744 *target_type = TARGET_TYPE_AR6320;
745 break;
746
747 case AR6320_FW_2_0:
748 case AR6320_FW_3_0:
749 case AR6320_FW_3_2:
750 *hif_type = HIF_TYPE_AR6320V2;
751 *target_type = TARGET_TYPE_AR6320V2;
752 break;
753
754 default:
755 HIF_ERROR("%s: error - dev_id = 0x%x, rev_id = 0x%x",
756 __func__, device_id, revision_id);
757 ret = -ENODEV;
758 goto end;
759 }
760 break;
761
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700762 case AR9887_DEVICE_ID:
763 *hif_type = HIF_TYPE_AR9888;
764 *target_type = TARGET_TYPE_AR9888;
Houston Hoffmanc50572b2016-06-08 19:49:46 -0700765 HIF_INFO(" *********** AR9887 **************");
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700766 break;
767
768 case QCA9984_DEVICE_ID:
769 *hif_type = HIF_TYPE_QCA9984;
770 *target_type = TARGET_TYPE_QCA9984;
Houston Hoffmanc50572b2016-06-08 19:49:46 -0700771 HIF_INFO(" *********** QCA9984 *************");
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700772 break;
773
774 case QCA9888_DEVICE_ID:
775 *hif_type = HIF_TYPE_QCA9888;
776 *target_type = TARGET_TYPE_QCA9888;
Houston Hoffmanc50572b2016-06-08 19:49:46 -0700777 HIF_INFO(" *********** QCA9888 *************");
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700778 break;
779
780 case AR900B_DEVICE_ID:
781 *hif_type = HIF_TYPE_AR900B;
782 *target_type = TARGET_TYPE_AR900B;
Houston Hoffmanc50572b2016-06-08 19:49:46 -0700783 HIF_INFO(" *********** AR900B *************");
Houston Hoffmanfb698ef2016-05-05 19:50:44 -0700784 break;
785
Houston Hoffman3db96a42016-05-05 19:54:39 -0700786 case IPQ4019_DEVICE_ID:
787 *hif_type = HIF_TYPE_IPQ4019;
788 *target_type = TARGET_TYPE_IPQ4019;
Houston Hoffmanc50572b2016-06-08 19:49:46 -0700789 HIF_INFO(" *********** IPQ4019 *************");
Houston Hoffman3db96a42016-05-05 19:54:39 -0700790 break;
791
Venkateswara Swamy Bandaru9fd9af02016-09-20 20:27:31 +0530792 case QCA8074_DEVICE_ID:
Karunakar Dasinenif61cb072016-09-29 11:50:45 -0700793 case RUMIM2M_DEVICE_ID_NODE0:
794 case RUMIM2M_DEVICE_ID_NODE1:
Sathish Kumar2d2f19a2017-02-13 15:52:07 +0530795 case RUMIM2M_DEVICE_ID_NODE2:
796 case RUMIM2M_DEVICE_ID_NODE3:
Venkateswara Swamy Bandaru9fd9af02016-09-20 20:27:31 +0530797 *hif_type = HIF_TYPE_QCA8074;
798 *target_type = TARGET_TYPE_QCA8074;
799 HIF_INFO(" *********** QCA8074 *************\n");
800 break;
801
Houston Hoffman31b25ec2016-09-19 13:12:30 -0700802 case QCA6290_EMULATION_DEVICE_ID:
Houston Hoffman14f621c2017-05-01 10:35:50 -0700803 case QCA6290_DEVICE_ID:
Houston Hoffman31b25ec2016-09-19 13:12:30 -0700804 *hif_type = HIF_TYPE_QCA6290;
805 *target_type = TARGET_TYPE_QCA6290;
806 HIF_INFO(" *********** QCA6290EMU *************\n");
807 break;
808
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800809 default:
810 HIF_ERROR("%s: Unsupported device ID!", __func__);
811 ret = -ENODEV;
812 break;
813 }
Houston Hoffman817ff7f2017-07-13 14:03:28 -0700814
815 if (*target_type == TARGET_TYPE_UNKNOWN) {
816 HIF_ERROR("%s: Unsupported target_type!", __func__);
817 ret = -ENODEV;
818 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800819end:
820 return ret;
821}
Komal Seelam91553ce2016-01-27 18:57:10 +0530822
823/**
Houston Hoffman26352592016-03-14 21:11:43 -0700824 * hif_needs_bmi() - return true if the soc needs bmi through the driver
825 * @hif_ctx: hif context
826 *
827 * Return: true if the soc needs driver bmi otherwise false
828 */
829bool hif_needs_bmi(struct hif_opaque_softc *hif_ctx)
830{
831 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx);
Pratik Gandhi815c6d82016-10-19 12:06:32 +0530832
Houston Hoffman6c0c3f92016-09-27 18:05:39 -0700833 return (hif_sc->bus_type != QDF_BUS_TYPE_SNOC) &&
834 !ce_srng_based(hif_sc);
Houston Hoffman26352592016-03-14 21:11:43 -0700835}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530836qdf_export_symbol(hif_needs_bmi);
Houston Hoffman26352592016-03-14 21:11:43 -0700837
838/**
Houston Hoffman60a1eeb2016-03-14 21:11:44 -0700839 * hif_get_bus_type() - return the bus type
840 *
841 * Return: enum qdf_bus_type
842 */
843enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl)
844{
845 struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700846
Houston Hoffman60a1eeb2016-03-14 21:11:44 -0700847 return scn->bus_type;
848}
849
850/**
Komal Seelam91553ce2016-01-27 18:57:10 +0530851 * Target info and ini parameters are global to the driver
852 * Hence these structures are exposed to all the modules in
853 * the driver and they don't need to maintains multiple copies
854 * of the same info, instead get the handle from hif and
855 * modify them in hif
856 */
857
858/**
859 * hif_get_ini_handle() - API to get hif_config_param handle
Komal Seelam644263d2016-02-22 20:45:49 +0530860 * @hif_ctx: HIF Context
Komal Seelam91553ce2016-01-27 18:57:10 +0530861 *
862 * Return: pointer to hif_config_info
863 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530864struct hif_config_info *hif_get_ini_handle(struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530865{
Komal Seelam644263d2016-02-22 20:45:49 +0530866 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
867
868 return &sc->hif_config;
Komal Seelam91553ce2016-01-27 18:57:10 +0530869}
870
871/**
872 * hif_get_target_info_handle() - API to get hif_target_info handle
Komal Seelam644263d2016-02-22 20:45:49 +0530873 * @hif_ctx: HIF context
Komal Seelam91553ce2016-01-27 18:57:10 +0530874 *
875 * Return: Pointer to hif_target_info
876 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530877struct hif_target_info *hif_get_target_info_handle(
878 struct hif_opaque_softc *hif_ctx)
Komal Seelam91553ce2016-01-27 18:57:10 +0530879{
Komal Seelam644263d2016-02-22 20:45:49 +0530880 struct hif_softc *sc = HIF_GET_SOFTC(hif_ctx);
881
882 return &sc->target_info;
883
Komal Seelam91553ce2016-01-27 18:57:10 +0530884}
Pratik Gandhidc82a772018-01-30 18:57:05 +0530885qdf_export_symbol(hif_get_target_info_handle);
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530886
887#if defined(FEATURE_LRO)
Manjunathappa Prakash2146da32016-10-13 14:47:47 -0700888
889/**
890 * hif_get_lro_info - Returns LRO instance for instance ID
891 * @ctx_id: LRO instance ID
892 * @hif_hdl: HIF Context
893 *
894 * Return: Pointer to LRO instance.
895 */
896void *hif_get_lro_info(int ctx_id, struct hif_opaque_softc *hif_hdl)
897{
898 void *data;
899
900 if (hif_napi_enabled(hif_hdl, -1))
901 data = hif_napi_get_lro_info(hif_hdl, ctx_id);
902 else
903 data = hif_ce_get_lro_ctx(hif_hdl, ctx_id);
904
905 return data;
906}
907
908/**
909 * hif_get_rx_ctx_id - Returns LRO instance ID based on underlying LRO instance
910 * @ctx_id: LRO context ID
911 * @hif_hdl: HIF Context
912 *
913 * Return: LRO instance ID
914 */
915int hif_get_rx_ctx_id(int ctx_id, struct hif_opaque_softc *hif_hdl)
916{
917 if (hif_napi_enabled(hif_hdl, -1))
918 return NAPI_PIPE2ID(ctx_id);
919 else
920 return ctx_id;
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530921}
922
Manjunathappa Prakash2146da32016-10-13 14:47:47 -0700923#else /* !defined(FEATURE_LRO) */
924int hif_get_rx_ctx_id(int ctx_id, struct hif_opaque_softc *hif_hdl)
925{
926 return 0;
Komal Seelamc92a0cf2016-02-22 20:43:52 +0530927}
928#endif
Komal Seelam644263d2016-02-22 20:45:49 +0530929
930/**
931 * hif_get_target_status - API to get target status
932 * @hif_ctx: HIF Context
933 *
Komal Seelam6ee55902016-04-11 17:11:07 +0530934 * Return: enum hif_target_status
Komal Seelam644263d2016-02-22 20:45:49 +0530935 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530936enum hif_target_status hif_get_target_status(struct hif_opaque_softc *hif_ctx)
Komal Seelam644263d2016-02-22 20:45:49 +0530937{
938 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
939
940 return scn->target_status;
941}
942
943/**
Komal Seelama5911d32016-02-24 19:21:59 +0530944 * hif_set_target_status() - API to set target status
Komal Seelam644263d2016-02-22 20:45:49 +0530945 * @hif_ctx: HIF Context
946 * @status: Target Status
947 *
948 * Return: void
949 */
Komal Seelam6ee55902016-04-11 17:11:07 +0530950void hif_set_target_status(struct hif_opaque_softc *hif_ctx, enum
951 hif_target_status status)
Komal Seelam644263d2016-02-22 20:45:49 +0530952{
953 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
954
955 scn->target_status = status;
956}
Komal Seelama5911d32016-02-24 19:21:59 +0530957
958/**
959 * hif_init_ini_config() - API to initialize HIF configuration parameters
960 * @hif_ctx: HIF Context
961 * @cfg: HIF Configuration
962 *
963 * Return: void
964 */
Komal Seelam5584a7c2016-02-24 19:22:48 +0530965void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
966 struct hif_config_info *cfg)
Komal Seelama5911d32016-02-24 19:21:59 +0530967{
968 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
969
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530970 qdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
Komal Seelama5911d32016-02-24 19:21:59 +0530971}
Komal Seelambd7c51d2016-02-24 10:27:30 +0530972
973/**
974 * hif_get_conparam() - API to get driver mode in HIF
975 * @scn: HIF Context
976 *
977 * Return: driver mode of operation
978 */
979uint32_t hif_get_conparam(struct hif_softc *scn)
980{
981 if (!scn)
982 return 0;
983
984 return scn->hif_con_param;
985}
986
987/**
988 * hif_get_callbacks_handle() - API to get callbacks Handle
989 * @scn: HIF Context
990 *
991 * Return: pointer to HIF Callbacks
992 */
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -0700993struct hif_driver_state_callbacks *hif_get_callbacks_handle(
994 struct hif_softc *scn)
Komal Seelambd7c51d2016-02-24 10:27:30 +0530995{
996 return &scn->callbacks;
997}
998
999/**
1000 * hif_is_driver_unloading() - API to query upper layers if driver is unloading
1001 * @scn: HIF Context
1002 *
1003 * Return: True/False
1004 */
1005bool hif_is_driver_unloading(struct hif_softc *scn)
1006{
Komal Seelam75080122016-03-02 15:18:25 +05301007 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +05301008
1009 if (cbk && cbk->is_driver_unloading)
1010 return cbk->is_driver_unloading(cbk->context);
1011
1012 return false;
1013}
1014
1015/**
1016 * hif_is_load_or_unload_in_progress() - API to query upper layers if
1017 * load/unload in progress
1018 * @scn: HIF Context
1019 *
1020 * Return: True/False
1021 */
1022bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
1023{
Komal Seelam75080122016-03-02 15:18:25 +05301024 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +05301025
1026 if (cbk && cbk->is_load_unload_in_progress)
1027 return cbk->is_load_unload_in_progress(cbk->context);
1028
1029 return false;
1030}
1031
1032/**
Venkateswara Swamy Bandaru26f6f1e2016-10-03 19:35:57 +05301033 * hif_update_pipe_callback() - API to register pipe specific callbacks
1034 * @osc: Opaque softc
1035 * @pipeid: pipe id
1036 * @callbacks: callbacks to register
1037 *
1038 * Return: void
1039 */
1040
1041void hif_update_pipe_callback(struct hif_opaque_softc *osc,
1042 u_int8_t pipeid,
1043 struct hif_msg_callbacks *callbacks)
1044{
1045 struct hif_softc *scn = HIF_GET_SOFTC(osc);
1046 struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
1047 struct HIF_CE_pipe_info *pipe_info;
1048
1049 QDF_BUG(pipeid < CE_COUNT_MAX);
1050
1051 HIF_INFO_LO("+%s pipeid %d\n", __func__, pipeid);
1052
1053 pipe_info = &hif_state->pipe_info[pipeid];
1054
1055 qdf_mem_copy(&pipe_info->pipe_callbacks,
1056 callbacks, sizeof(pipe_info->pipe_callbacks));
1057
1058 HIF_INFO_LO("-%s\n", __func__);
1059}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301060qdf_export_symbol(hif_update_pipe_callback);
Venkateswara Swamy Bandaru26f6f1e2016-10-03 19:35:57 +05301061
1062/**
Komal Seelambd7c51d2016-02-24 10:27:30 +05301063 * hif_is_recovery_in_progress() - API to query upper layers if recovery in
1064 * progress
1065 * @scn: HIF Context
1066 *
1067 * Return: True/False
1068 */
1069bool hif_is_recovery_in_progress(struct hif_softc *scn)
1070{
Komal Seelam75080122016-03-02 15:18:25 +05301071 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
Komal Seelambd7c51d2016-02-24 10:27:30 +05301072
1073 if (cbk && cbk->is_recovery_in_progress)
1074 return cbk->is_recovery_in_progress(cbk->context);
1075
1076 return false;
1077}
Govind Singhbc679dc2017-06-08 12:33:59 +05301078
1079/**
1080 * hif_is_target_ready() - API to query if target is in ready state
1081 * progress
1082 * @scn: HIF Context
1083 *
1084 * Return: True/False
1085 */
1086bool hif_is_target_ready(struct hif_softc *scn)
1087{
1088 struct hif_driver_state_callbacks *cbk = hif_get_callbacks_handle(scn);
1089
1090 if (cbk && cbk->is_target_ready)
1091 return cbk->is_target_ready(cbk->context);
1092
1093 return false;
1094}
Mohit Khanna440c5292016-05-12 11:05:06 -07001095#if defined(HIF_PCI) || defined(SNOC) || defined(HIF_AHB)
Houston Hoffman56e0d702016-05-05 17:48:06 -07001096/**
1097 * hif_batch_send() - API to access hif specific function
1098 * ce_batch_send.
1099 * @osc: HIF Context
1100 * @msdu : list of msdus to be sent
1101 * @transfer_id : transfer id
1102 * @len : donwloaded length
1103 *
1104 * Return: list of msds not sent
1105 */
1106qdf_nbuf_t hif_batch_send(struct hif_opaque_softc *osc, qdf_nbuf_t msdu,
1107 uint32_t transfer_id, u_int32_t len, uint32_t sendhead)
1108{
1109 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +05301110
Houston Hoffman56e0d702016-05-05 17:48:06 -07001111 return ce_batch_send((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
1112 len, sendhead);
1113}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301114qdf_export_symbol(hif_batch_send);
Houston Hoffman56e0d702016-05-05 17:48:06 -07001115
1116/**
1117 * hif_update_tx_ring() - API to access hif specific function
1118 * ce_update_tx_ring.
1119 * @osc: HIF Context
1120 * @num_htt_cmpls : number of htt compl received.
1121 *
1122 * Return: void
1123 */
1124void hif_update_tx_ring(struct hif_opaque_softc *osc, u_int32_t num_htt_cmpls)
1125{
1126 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -07001127
Houston Hoffman56e0d702016-05-05 17:48:06 -07001128 ce_update_tx_ring(ce_tx_hdl, num_htt_cmpls);
1129}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301130qdf_export_symbol(hif_update_tx_ring);
Houston Hoffman56e0d702016-05-05 17:48:06 -07001131
1132
1133/**
1134 * hif_send_single() - API to access hif specific function
1135 * ce_send_single.
1136 * @osc: HIF Context
1137 * @msdu : msdu to be sent
1138 * @transfer_id: transfer id
1139 * @len : downloaded length
1140 *
1141 * Return: msdu sent status
1142 */
1143int hif_send_single(struct hif_opaque_softc *osc, qdf_nbuf_t msdu, uint32_t
1144 transfer_id, u_int32_t len)
1145{
1146 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +05301147
Houston Hoffman56e0d702016-05-05 17:48:06 -07001148 return ce_send_single((struct CE_handle *)ce_tx_hdl, msdu, transfer_id,
1149 len);
1150}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301151qdf_export_symbol(hif_send_single);
Houston Hoffman56e0d702016-05-05 17:48:06 -07001152
1153/**
1154 * hif_send_fast() - API to access hif specific function
1155 * ce_send_fast.
1156 * @osc: HIF Context
1157 * @msdu : array of msdus to be sent
1158 * @num_msdus : number of msdus in an array
1159 * @transfer_id: transfer id
Nirav Shahda0881a2016-05-16 10:45:16 +05301160 * @download_len: download length
Houston Hoffman56e0d702016-05-05 17:48:06 -07001161 *
1162 * Return: No. of packets that could be sent
1163 */
Nirav Shahda0881a2016-05-16 10:45:16 +05301164int hif_send_fast(struct hif_opaque_softc *osc, qdf_nbuf_t nbuf,
1165 uint32_t transfer_id, uint32_t download_len)
Houston Hoffman56e0d702016-05-05 17:48:06 -07001166{
1167 void *ce_tx_hdl = hif_get_ce_handle(osc, CE_HTT_TX_CE);
Kiran Venkatappaf41ef2e2016-09-05 10:59:58 +05301168
Nirav Shahda0881a2016-05-16 10:45:16 +05301169 return ce_send_fast((struct CE_handle *)ce_tx_hdl, nbuf,
1170 transfer_id, download_len);
Houston Hoffman56e0d702016-05-05 17:48:06 -07001171}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301172qdf_export_symbol(hif_send_fast);
Mohit Khanna440c5292016-05-12 11:05:06 -07001173#endif
Houston Hoffman56e0d702016-05-05 17:48:06 -07001174
1175/**
1176 * hif_reg_write() - API to access hif specific function
1177 * hif_write32_mb.
1178 * @hif_ctx : HIF Context
1179 * @offset : offset on which value has to be written
1180 * @value : value to be written
1181 *
1182 * Return: None
1183 */
1184void hif_reg_write(struct hif_opaque_softc *hif_ctx, uint32_t offset,
1185 uint32_t value)
1186{
1187 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -07001188
Houston Hoffman56e0d702016-05-05 17:48:06 -07001189 hif_write32_mb(scn->mem + offset, value);
1190
1191}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301192qdf_export_symbol(hif_reg_write);
Houston Hoffman56e0d702016-05-05 17:48:06 -07001193
1194/**
1195 * hif_reg_read() - API to access hif specific function
1196 * hif_read32_mb.
1197 * @hif_ctx : HIF Context
1198 * @offset : offset from which value has to be read
1199 *
1200 * Return: Read value
1201 */
1202uint32_t hif_reg_read(struct hif_opaque_softc *hif_ctx, uint32_t offset)
1203{
1204
1205 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
Manikandan Mohanbd0ef8a2017-04-10 13:10:21 -07001206
Houston Hoffman56e0d702016-05-05 17:48:06 -07001207 return hif_read32_mb(scn->mem + offset);
1208}
Pratik Gandhidc82a772018-01-30 18:57:05 +05301209qdf_export_symbol(hif_reg_read);
Mohit Khanna440c5292016-05-12 11:05:06 -07001210
1211#if defined(HIF_USB)
1212/**
1213 * hif_ramdump_handler(): generic ramdump handler
1214 * @scn: struct hif_opaque_softc
1215 *
1216 * Return: None
1217 */
1218
1219void hif_ramdump_handler(struct hif_opaque_softc *scn)
1220
1221{
1222 if (hif_get_bus_type == QDF_BUS_TYPE_USB)
1223 hif_usb_ramdump_handler();
1224}
1225#endif
Venkateswara Swamy Bandaru31108f32016-08-08 18:04:29 +05301226
Dustin Brown2af3d672017-05-30 16:14:01 -07001227#ifdef WLAN_SUSPEND_RESUME_TEST
1228irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
1229{
1230 struct hif_softc *scn = context;
1231
1232 HIF_INFO("wake interrupt received on irq %d", irq);
1233
Dustin Brownbbba9172017-10-04 17:03:56 -07001234 if (scn->initial_wakeup_cb)
1235 scn->initial_wakeup_cb(scn->initial_wakeup_priv);
1236
Dustin Brown2af3d672017-05-30 16:14:01 -07001237 if (hif_is_ut_suspended(scn))
1238 hif_ut_fw_resume(scn);
1239
1240 return IRQ_HANDLED;
1241}
1242#else /* WLAN_SUSPEND_RESUME_TEST */
1243irqreturn_t hif_wake_interrupt_handler(int irq, void *context)
1244{
Dustin Brownbbba9172017-10-04 17:03:56 -07001245 struct hif_softc *scn = context;
1246
Dustin Brown2af3d672017-05-30 16:14:01 -07001247 HIF_INFO("wake interrupt received on irq %d", irq);
1248
Dustin Brownbbba9172017-10-04 17:03:56 -07001249 if (scn->initial_wakeup_cb)
1250 scn->initial_wakeup_cb(scn->initial_wakeup_priv);
1251
Dustin Brown2af3d672017-05-30 16:14:01 -07001252 return IRQ_HANDLED;
1253}
1254#endif /* WLAN_SUSPEND_RESUME_TEST */
Dustin Brownbbba9172017-10-04 17:03:56 -07001255
1256void hif_set_initial_wakeup_cb(struct hif_opaque_softc *hif_ctx,
1257 void (*callback)(void *),
1258 void *priv)
1259{
1260 struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
1261
1262 scn->initial_wakeup_cb = callback;
1263 scn->initial_wakeup_priv = priv;
1264}
1265