blob: ab02b745d1b5a02ed50c92988787af88473ec19a [file] [log] [blame]
Yue Ma0317e4a2018-01-10 11:48:32 -08001/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/delay.h>
14#include <linux/jiffies.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18#include <linux/pm_wakeup.h>
19#include <linux/rwsem.h>
20#include <linux/suspend.h>
21#include <linux/timer.h>
22#include <soc/qcom/ramdump.h>
23#include <soc/qcom/subsystem_notif.h>
24
25#include "main.h"
26#include "debug.h"
27#include "pci.h"
28
29#define CNSS_DUMP_FORMAT_VER 0x11
30#define CNSS_DUMP_FORMAT_VER_V2 0x22
31#define CNSS_DUMP_MAGIC_VER_V2 0x42445953
32#define CNSS_DUMP_NAME "CNSS_WLAN"
33#define CNSS_DUMP_DESC_SIZE 0x1000
34#define CNSS_DUMP_SEG_VER 0x1
35#define WLAN_RECOVERY_DELAY 1000
36#define FILE_SYSTEM_READY 1
37#define FW_READY_TIMEOUT 20000
38#define FW_ASSERT_TIMEOUT 5000
39#define CNSS_EVENT_PENDING 2989
40#define WAKE_MSI_NAME "WAKE"
41
42static struct cnss_plat_data *plat_env;
43
44static DECLARE_RWSEM(cnss_pm_sem);
45
46static bool qmi_bypass;
47#ifdef CONFIG_CNSS2_DEBUG
48module_param(qmi_bypass, bool, 0600);
49MODULE_PARM_DESC(qmi_bypass, "Bypass QMI from platform driver");
50#endif
51
52static bool enable_waltest;
53#ifdef CONFIG_CNSS2_DEBUG
54module_param(enable_waltest, bool, 0600);
55MODULE_PARM_DESC(enable_waltest, "Enable to handle firmware waltest");
56#endif
57
58enum cnss_debug_quirks {
59 LINK_DOWN_SELF_RECOVERY,
60 SKIP_DEVICE_BOOT,
61 USE_CORE_ONLY_FW,
62 SKIP_RECOVERY,
63};
64
65unsigned long quirks;
66#ifdef CONFIG_CNSS2_DEBUG
67module_param(quirks, ulong, 0600);
68MODULE_PARM_DESC(quirks, "Debug quirks for the driver");
69#endif
70
71static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = {
72 "qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin",
73 "utfbd30.bin", "epping30.bin", "evicted30.bin"
74};
75
76static struct cnss_fw_files FW_FILES_DEFAULT = {
77 "qwlan.bin", "bdwlan.bin", "otp.bin", "utf.bin",
78 "utfbd.bin", "epping.bin", "evicted.bin"
79};
80
81struct cnss_driver_event {
82 struct list_head list;
83 enum cnss_driver_event_type type;
84 bool sync;
85 struct completion complete;
86 int ret;
87 void *data;
88};
89
90static enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
91{
92 if (!dev)
93 return CNSS_BUS_NONE;
94
95 if (!dev->bus)
96 return CNSS_BUS_NONE;
97
98 if (memcmp(dev->bus->name, "pci", 3) == 0)
99 return CNSS_BUS_PCI;
100 else
101 return CNSS_BUS_NONE;
102}
103
104static void cnss_set_plat_priv(struct platform_device *plat_dev,
105 struct cnss_plat_data *plat_priv)
106{
107 plat_env = plat_priv;
108}
109
110static struct cnss_plat_data *cnss_get_plat_priv(struct platform_device
111 *plat_dev)
112{
113 return plat_env;
114}
115
116void *cnss_bus_dev_to_bus_priv(struct device *dev)
117{
118 if (!dev)
119 return NULL;
120
121 switch (cnss_get_dev_bus_type(dev)) {
122 case CNSS_BUS_PCI:
123 return cnss_get_pci_priv(to_pci_dev(dev));
124 default:
125 return NULL;
126 }
127}
128
129struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev)
130{
131 void *bus_priv;
132
133 if (!dev)
134 return cnss_get_plat_priv(NULL);
135
136 bus_priv = cnss_bus_dev_to_bus_priv(dev);
137 if (!bus_priv)
138 return NULL;
139
140 switch (cnss_get_dev_bus_type(dev)) {
141 case CNSS_BUS_PCI:
142 return cnss_pci_priv_to_plat_priv(bus_priv);
143 default:
144 return NULL;
145 }
146}
147
148static int cnss_pm_notify(struct notifier_block *b,
149 unsigned long event, void *p)
150{
151 switch (event) {
152 case PM_SUSPEND_PREPARE:
153 down_write(&cnss_pm_sem);
154 break;
155 case PM_POST_SUSPEND:
156 up_write(&cnss_pm_sem);
157 break;
158 }
159
160 return NOTIFY_DONE;
161}
162
163static struct notifier_block cnss_pm_notifier = {
164 .notifier_call = cnss_pm_notify,
165};
166
167static void cnss_pm_stay_awake(struct cnss_plat_data *plat_priv)
168{
169 if (atomic_inc_return(&plat_priv->pm_count) != 1)
170 return;
171
172 cnss_pr_dbg("PM stay awake, state: 0x%lx, count: %d\n",
173 plat_priv->driver_state,
174 atomic_read(&plat_priv->pm_count));
175 pm_stay_awake(&plat_priv->plat_dev->dev);
176}
177
178static void cnss_pm_relax(struct cnss_plat_data *plat_priv)
179{
180 int r = atomic_dec_return(&plat_priv->pm_count);
181
182 WARN_ON(r < 0);
183
184 if (r != 0)
185 return;
186
187 cnss_pr_dbg("PM relax, state: 0x%lx, count: %d\n",
188 plat_priv->driver_state,
189 atomic_read(&plat_priv->pm_count));
190 pm_relax(&plat_priv->plat_dev->dev);
191}
192
193void cnss_lock_pm_sem(struct device *dev)
194{
195 down_read(&cnss_pm_sem);
196}
197EXPORT_SYMBOL(cnss_lock_pm_sem);
198
199void cnss_release_pm_sem(struct device *dev)
200{
201 up_read(&cnss_pm_sem);
202}
203EXPORT_SYMBOL(cnss_release_pm_sem);
204
205int cnss_get_fw_files_for_target(struct device *dev,
206 struct cnss_fw_files *pfw_files,
207 u32 target_type, u32 target_version)
208{
209 if (!pfw_files)
210 return -ENODEV;
211
212 switch (target_version) {
213 case QCA6174_REV3_VERSION:
214 case QCA6174_REV3_2_VERSION:
215 memcpy(pfw_files, &FW_FILES_QCA6174_FW_3_0, sizeof(*pfw_files));
216 break;
217 default:
218 memcpy(pfw_files, &FW_FILES_DEFAULT, sizeof(*pfw_files));
219 cnss_pr_err("Unknown target version, type: 0x%X, version: 0x%X",
220 target_type, target_version);
221 break;
222 }
223
224 return 0;
225}
226EXPORT_SYMBOL(cnss_get_fw_files_for_target);
227
228int cnss_request_bus_bandwidth(struct device *dev, int bandwidth)
229{
230 int ret = 0;
231 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
232 struct cnss_bus_bw_info *bus_bw_info;
233
234 if (!plat_priv)
235 return -ENODEV;
236
237 bus_bw_info = &plat_priv->bus_bw_info;
238 if (!bus_bw_info->bus_client)
239 return -EINVAL;
240
241 switch (bandwidth) {
242 case CNSS_BUS_WIDTH_NONE:
243 case CNSS_BUS_WIDTH_LOW:
244 case CNSS_BUS_WIDTH_MEDIUM:
245 case CNSS_BUS_WIDTH_HIGH:
246 ret = msm_bus_scale_client_update_request(
247 bus_bw_info->bus_client, bandwidth);
248 if (!ret)
249 bus_bw_info->current_bw_vote = bandwidth;
250 else
251 cnss_pr_err("Could not set bus bandwidth: %d, err = %d\n",
252 bandwidth, ret);
253 break;
254 default:
255 cnss_pr_err("Invalid bus bandwidth: %d", bandwidth);
256 ret = -EINVAL;
257 }
258
259 return ret;
260}
261EXPORT_SYMBOL(cnss_request_bus_bandwidth);
262
263int cnss_get_platform_cap(struct device *dev, struct cnss_platform_cap *cap)
264{
265 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
266
267 if (!plat_priv)
268 return -ENODEV;
269
270 if (cap)
271 *cap = plat_priv->cap;
272
273 return 0;
274}
275EXPORT_SYMBOL(cnss_get_platform_cap);
276
277int cnss_get_soc_info(struct device *dev, struct cnss_soc_info *info)
278{
279 int ret = 0;
280 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
281 void *bus_priv = cnss_bus_dev_to_bus_priv(dev);
282
283 if (!plat_priv)
284 return -ENODEV;
285
286 ret = cnss_pci_get_bar_info(bus_priv, &info->va, &info->pa);
287 if (ret)
288 return ret;
289
290 return 0;
291}
292EXPORT_SYMBOL(cnss_get_soc_info);
293
294void cnss_request_pm_qos(struct device *dev, u32 qos_val)
295{
296 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
297
298 if (!plat_priv)
299 return;
300
301 pm_qos_add_request(&plat_priv->qos_request, PM_QOS_CPU_DMA_LATENCY,
302 qos_val);
303}
304EXPORT_SYMBOL(cnss_request_pm_qos);
305
306void cnss_remove_pm_qos(struct device *dev)
307{
308 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
309
310 if (!plat_priv)
311 return;
312
313 pm_qos_remove_request(&plat_priv->qos_request);
314}
315EXPORT_SYMBOL(cnss_remove_pm_qos);
316
317int cnss_wlan_enable(struct device *dev,
318 struct cnss_wlan_enable_cfg *config,
319 enum cnss_driver_mode mode,
320 const char *host_version)
321{
322 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
323 struct wlfw_wlan_cfg_req_msg_v01 req;
324 u32 i;
325 int ret = 0;
326
327 if (plat_priv->device_id == QCA6174_DEVICE_ID)
328 return 0;
329
330 if (qmi_bypass)
331 return 0;
332
333 if (!config || !host_version) {
334 cnss_pr_err("Invalid config or host_version pointer\n");
335 return -EINVAL;
336 }
337
338 cnss_pr_dbg("Mode: %d, config: %pK, host_version: %s\n",
339 mode, config, host_version);
340
341 if (mode == CNSS_WALTEST || mode == CNSS_CCPM)
342 goto skip_cfg;
343
344 memset(&req, 0, sizeof(req));
345
346 req.host_version_valid = 1;
347 strlcpy(req.host_version, host_version,
348 QMI_WLFW_MAX_STR_LEN_V01 + 1);
349
350 req.tgt_cfg_valid = 1;
351 if (config->num_ce_tgt_cfg > QMI_WLFW_MAX_NUM_CE_V01)
352 req.tgt_cfg_len = QMI_WLFW_MAX_NUM_CE_V01;
353 else
354 req.tgt_cfg_len = config->num_ce_tgt_cfg;
355 for (i = 0; i < req.tgt_cfg_len; i++) {
356 req.tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num;
357 req.tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir;
358 req.tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries;
359 req.tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max;
360 req.tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags;
361 }
362
363 req.svc_cfg_valid = 1;
364 if (config->num_ce_svc_pipe_cfg > QMI_WLFW_MAX_NUM_SVC_V01)
365 req.svc_cfg_len = QMI_WLFW_MAX_NUM_SVC_V01;
366 else
367 req.svc_cfg_len = config->num_ce_svc_pipe_cfg;
368 for (i = 0; i < req.svc_cfg_len; i++) {
369 req.svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id;
370 req.svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir;
371 req.svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
372 }
373
374 req.shadow_reg_v2_valid = 1;
375 if (config->num_shadow_reg_v2_cfg >
376 QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01)
377 req.shadow_reg_v2_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01;
378 else
379 req.shadow_reg_v2_len = config->num_shadow_reg_v2_cfg;
380
381 memcpy(req.shadow_reg_v2, config->shadow_reg_v2_cfg,
382 sizeof(struct wlfw_shadow_reg_v2_cfg_s_v01)
383 * req.shadow_reg_v2_len);
384
385 ret = cnss_wlfw_wlan_cfg_send_sync(plat_priv, &req);
386 if (ret)
387 goto out;
388
389skip_cfg:
390 ret = cnss_wlfw_wlan_mode_send_sync(plat_priv, mode);
391out:
392 return ret;
393}
394EXPORT_SYMBOL(cnss_wlan_enable);
395
396int cnss_wlan_disable(struct device *dev, enum cnss_driver_mode mode)
397{
398 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
399
400 if (plat_priv->device_id == QCA6174_DEVICE_ID)
401 return 0;
402
403 if (qmi_bypass)
404 return 0;
405
406 return cnss_wlfw_wlan_mode_send_sync(plat_priv, QMI_WLFW_OFF_V01);
407}
408EXPORT_SYMBOL(cnss_wlan_disable);
409
410#ifdef CONFIG_CNSS2_DEBUG
411int cnss_athdiag_read(struct device *dev, u32 offset, u32 mem_type,
412 u32 data_len, u8 *output)
413{
414 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
415 int ret = 0;
416
417 if (!plat_priv) {
418 cnss_pr_err("plat_priv is NULL!\n");
419 return -EINVAL;
420 }
421
422 if (plat_priv->device_id == QCA6174_DEVICE_ID)
423 return 0;
424
425 if (!output || data_len == 0 || data_len > QMI_WLFW_MAX_DATA_SIZE_V01) {
426 cnss_pr_err("Invalid parameters for athdiag read: output %p, data_len %u\n",
427 output, data_len);
428 ret = -EINVAL;
429 goto out;
430 }
431
432 if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
433 cnss_pr_err("Invalid state for athdiag read: 0x%lx\n",
434 plat_priv->driver_state);
435 ret = -EINVAL;
436 goto out;
437 }
438
439 ret = cnss_wlfw_athdiag_read_send_sync(plat_priv, offset, mem_type,
440 data_len, output);
441
442out:
443 return ret;
444}
445EXPORT_SYMBOL(cnss_athdiag_read);
446
447int cnss_athdiag_write(struct device *dev, u32 offset, u32 mem_type,
448 u32 data_len, u8 *input)
449{
450 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
451 int ret = 0;
452
453 if (!plat_priv) {
454 cnss_pr_err("plat_priv is NULL!\n");
455 return -EINVAL;
456 }
457
458 if (plat_priv->device_id == QCA6174_DEVICE_ID)
459 return 0;
460
461 if (!input || data_len == 0 || data_len > QMI_WLFW_MAX_DATA_SIZE_V01) {
462 cnss_pr_err("Invalid parameters for athdiag write: input %p, data_len %u\n",
463 input, data_len);
464 ret = -EINVAL;
465 goto out;
466 }
467
468 if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
469 cnss_pr_err("Invalid state for athdiag write: 0x%lx\n",
470 plat_priv->driver_state);
471 ret = -EINVAL;
472 goto out;
473 }
474
475 ret = cnss_wlfw_athdiag_write_send_sync(plat_priv, offset, mem_type,
476 data_len, input);
477
478out:
479 return ret;
480}
481EXPORT_SYMBOL(cnss_athdiag_write);
482#else
483int cnss_athdiag_read(struct device *dev, u32 offset, u32 mem_type,
484 u32 data_len, u8 *output)
485{
486 return -EPERM;
487}
488EXPORT_SYMBOL(cnss_athdiag_read);
489
490int cnss_athdiag_write(struct device *dev, u32 offset, u32 mem_type,
491 u32 data_len, u8 *input)
492{
493 return -EPERM;
494}
495EXPORT_SYMBOL(cnss_athdiag_write);
496#endif
497
498int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
499{
500 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
501
502 if (plat_priv->device_id == QCA6174_DEVICE_ID)
503 return 0;
504
505 return cnss_wlfw_ini_send_sync(plat_priv, fw_log_mode);
506}
507EXPORT_SYMBOL(cnss_set_fw_log_mode);
508
509u32 cnss_get_wake_msi(struct cnss_plat_data *plat_priv)
510{
511 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
512 int ret, num_vectors;
513 u32 user_base_data, base_vector;
514
515 ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
516 WAKE_MSI_NAME, &num_vectors,
517 &user_base_data, &base_vector);
518
519 if (ret) {
520 cnss_pr_err("WAKE MSI is not valid\n");
521 return 0;
522 }
523
524 return user_base_data;
525}
526
527static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
528{
529 int ret = 0;
530
531 if (!plat_priv)
532 return -ENODEV;
533
534 set_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
535
536 ret = cnss_wlfw_tgt_cap_send_sync(plat_priv);
537 if (ret)
538 goto out;
539
540 ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv);
541 if (ret)
542 goto out;
543
544 ret = cnss_pci_load_m3(plat_priv->bus_priv);
545 if (ret)
546 goto out;
547
548 ret = cnss_wlfw_m3_dnld_send_sync(plat_priv);
549 if (ret)
550 goto out;
551
552 return 0;
553out:
554 return ret;
555}
556
557static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv)
558{
559 int ret = 0;
560 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
561
562 if (test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
563 clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
564 cnss_pr_dbg("Skip driver probe\n");
565 goto out;
566 }
567
568 if (!plat_priv->driver_ops) {
569 cnss_pr_err("driver_ops is NULL\n");
570 ret = -EINVAL;
571 goto out;
572 }
573
574 if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
575 ret = plat_priv->driver_ops->reinit(pci_priv->pci_dev,
576 pci_priv->pci_device_id);
577 if (ret) {
578 cnss_pr_err("Failed to reinit host driver, err = %d\n",
579 ret);
580 goto out;
581 }
582 clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
583 } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) {
584 ret = plat_priv->driver_ops->probe(pci_priv->pci_dev,
585 pci_priv->pci_device_id);
586 if (ret) {
587 cnss_pr_err("Failed to probe host driver, err = %d\n",
588 ret);
589 goto out;
590 }
591 clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
592 set_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
593 }
594
595 return 0;
596
597out:
598 return ret;
599}
600
601static int cnss_driver_call_remove(struct cnss_plat_data *plat_priv)
602{
603 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
604
605 if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state) ||
606 test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state) ||
607 test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
608 cnss_pr_dbg("Skip driver remove\n");
609 return 0;
610 }
611
612 if (!plat_priv->driver_ops) {
613 cnss_pr_err("driver_ops is NULL\n");
614 return -EINVAL;
615 }
616
617 if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
618 plat_priv->driver_ops->shutdown(pci_priv->pci_dev);
619 } else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
620 plat_priv->driver_ops->remove(pci_priv->pci_dev);
621 clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
622 }
623
624 return 0;
625}
626
627static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
628{
629 int ret = 0;
630
631 if (!plat_priv)
632 return -ENODEV;
633
634 del_timer(&plat_priv->fw_boot_timer);
635 set_bit(CNSS_FW_READY, &plat_priv->driver_state);
636
637 if (test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state)) {
638 clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
639 clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
640 }
641
642 if (enable_waltest) {
643 ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
644 QMI_WLFW_WALTEST_V01);
645 } else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) {
646 ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
647 QMI_WLFW_CALIBRATION_V01);
648 } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
649 test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
650 ret = cnss_driver_call_probe(plat_priv);
651 } else {
652 complete(&plat_priv->power_up_complete);
653 }
654
655 if (ret)
656 goto shutdown;
657
658 return 0;
659
660shutdown:
661 cnss_pci_stop_mhi(plat_priv->bus_priv);
662 cnss_suspend_pci_link(plat_priv->bus_priv);
663 cnss_power_off_device(plat_priv);
664
665 return ret;
666}
667
668static char *cnss_driver_event_to_str(enum cnss_driver_event_type type)
669{
670 switch (type) {
671 case CNSS_DRIVER_EVENT_SERVER_ARRIVE:
672 return "SERVER_ARRIVE";
673 case CNSS_DRIVER_EVENT_SERVER_EXIT:
674 return "SERVER_EXIT";
675 case CNSS_DRIVER_EVENT_REQUEST_MEM:
676 return "REQUEST_MEM";
677 case CNSS_DRIVER_EVENT_FW_MEM_READY:
678 return "FW_MEM_READY";
679 case CNSS_DRIVER_EVENT_FW_READY:
680 return "FW_READY";
681 case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START:
682 return "COLD_BOOT_CAL_START";
683 case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE:
684 return "COLD_BOOT_CAL_DONE";
685 case CNSS_DRIVER_EVENT_REGISTER_DRIVER:
686 return "REGISTER_DRIVER";
687 case CNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
688 return "UNREGISTER_DRIVER";
689 case CNSS_DRIVER_EVENT_RECOVERY:
690 return "RECOVERY";
691 case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
692 return "FORCE_FW_ASSERT";
693 case CNSS_DRIVER_EVENT_POWER_UP:
694 return "POWER_UP";
695 case CNSS_DRIVER_EVENT_POWER_DOWN:
696 return "POWER_DOWN";
697 case CNSS_DRIVER_EVENT_MAX:
698 return "EVENT_MAX";
699 }
700
701 return "UNKNOWN";
702};
703
704int cnss_driver_event_post(struct cnss_plat_data *plat_priv,
705 enum cnss_driver_event_type type,
706 u32 flags, void *data)
707{
708 struct cnss_driver_event *event;
709 unsigned long irq_flags;
710 int gfp = GFP_KERNEL;
711 int ret = 0;
712
713 if (!plat_priv)
714 return -ENODEV;
715
716 cnss_pr_dbg("Posting event: %s(%d)%s, state: 0x%lx flags: 0x%0x\n",
717 cnss_driver_event_to_str(type), type,
718 flags ? "-sync" : "", plat_priv->driver_state, flags);
719
720 if (type >= CNSS_DRIVER_EVENT_MAX) {
721 cnss_pr_err("Invalid Event type: %d, can't post", type);
722 return -EINVAL;
723 }
724
725 if (in_interrupt() || irqs_disabled())
726 gfp = GFP_ATOMIC;
727
728 event = kzalloc(sizeof(*event), gfp);
729 if (!event)
730 return -ENOMEM;
731
732 cnss_pm_stay_awake(plat_priv);
733
734 event->type = type;
735 event->data = data;
736 init_completion(&event->complete);
737 event->ret = CNSS_EVENT_PENDING;
738 event->sync = !!(flags & CNSS_EVENT_SYNC);
739
740 spin_lock_irqsave(&plat_priv->event_lock, irq_flags);
741 list_add_tail(&event->list, &plat_priv->event_list);
742 spin_unlock_irqrestore(&plat_priv->event_lock, irq_flags);
743
744 queue_work(plat_priv->event_wq, &plat_priv->event_work);
745
746 if (!(flags & CNSS_EVENT_SYNC))
747 goto out;
748
749 if (flags & CNSS_EVENT_UNINTERRUPTIBLE)
750 wait_for_completion(&event->complete);
751 else
752 ret = wait_for_completion_interruptible(&event->complete);
753
754 cnss_pr_dbg("Completed event: %s(%d), state: 0x%lx, ret: %d/%d\n",
755 cnss_driver_event_to_str(type), type,
756 plat_priv->driver_state, ret, event->ret);
757 spin_lock_irqsave(&plat_priv->event_lock, irq_flags);
758 if (ret == -ERESTARTSYS && event->ret == CNSS_EVENT_PENDING) {
759 event->sync = false;
760 spin_unlock_irqrestore(&plat_priv->event_lock, irq_flags);
761 ret = -EINTR;
762 goto out;
763 }
764 spin_unlock_irqrestore(&plat_priv->event_lock, irq_flags);
765
766 ret = event->ret;
767 kfree(event);
768
769out:
770 cnss_pm_relax(plat_priv);
771 return ret;
772}
773
774int cnss_power_up(struct device *dev)
775{
776 int ret = 0;
777 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
778 unsigned int timeout;
779
780 if (!plat_priv) {
781 cnss_pr_err("plat_priv is NULL\n");
782 return -ENODEV;
783 }
784
785 cnss_pr_dbg("Powering up device\n");
786
787 ret = cnss_driver_event_post(plat_priv,
788 CNSS_DRIVER_EVENT_POWER_UP,
789 CNSS_EVENT_SYNC, NULL);
790 if (ret)
791 goto out;
792
793 if (plat_priv->device_id == QCA6174_DEVICE_ID)
794 goto out;
795
796 timeout = cnss_get_qmi_timeout();
797
798 reinit_completion(&plat_priv->power_up_complete);
799 ret = wait_for_completion_timeout(&plat_priv->power_up_complete,
800 msecs_to_jiffies(timeout) << 2);
801 if (!ret) {
802 cnss_pr_err("Timeout waiting for power up to complete\n");
803 ret = -EAGAIN;
804 goto out;
805 }
806
807 return 0;
808
809out:
810 return ret;
811}
812EXPORT_SYMBOL(cnss_power_up);
813
814int cnss_power_down(struct device *dev)
815{
816 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
817
818 if (!plat_priv) {
819 cnss_pr_err("plat_priv is NULL\n");
820 return -ENODEV;
821 }
822
823 cnss_pr_dbg("Powering down device\n");
824
825 return cnss_driver_event_post(plat_priv,
826 CNSS_DRIVER_EVENT_POWER_DOWN,
827 CNSS_EVENT_SYNC, NULL);
828}
829EXPORT_SYMBOL(cnss_power_down);
830
831int cnss_wlan_register_driver(struct cnss_wlan_driver *driver_ops)
832{
833 int ret = 0;
834 struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);
835
836 if (!plat_priv) {
837 cnss_pr_err("plat_priv is NULL!\n");
838 return -ENODEV;
839 }
840
841 if (plat_priv->driver_ops) {
842 cnss_pr_err("Driver has already registered!\n");
843 return -EEXIST;
844 }
845
846 ret = cnss_driver_event_post(plat_priv,
847 CNSS_DRIVER_EVENT_REGISTER_DRIVER,
848 CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
849 driver_ops);
850 return ret;
851}
852EXPORT_SYMBOL(cnss_wlan_register_driver);
853
854void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops)
855{
856 struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);
857
858 if (!plat_priv) {
859 cnss_pr_err("plat_priv is NULL!\n");
860 return;
861 }
862
863 cnss_driver_event_post(plat_priv,
864 CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
865 CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
866}
867EXPORT_SYMBOL(cnss_wlan_unregister_driver);
868
869static int cnss_get_resources(struct cnss_plat_data *plat_priv)
870{
871 int ret = 0;
872
873 ret = cnss_get_vreg(plat_priv);
874 if (ret) {
875 cnss_pr_err("Failed to get vreg, err = %d\n", ret);
876 goto out;
877 }
878
879 ret = cnss_get_pinctrl(plat_priv);
880 if (ret) {
881 cnss_pr_err("Failed to get pinctrl, err = %d\n", ret);
882 goto out;
883 }
884
885 return 0;
886out:
887 return ret;
888}
889
890static void cnss_put_resources(struct cnss_plat_data *plat_priv)
891{
892}
893
894static int cnss_modem_notifier_nb(struct notifier_block *nb,
895 unsigned long code,
896 void *ss_handle)
897{
898 struct cnss_plat_data *plat_priv =
899 container_of(nb, struct cnss_plat_data, modem_nb);
900 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
901 struct cnss_esoc_info *esoc_info;
902 struct cnss_wlan_driver *driver_ops;
903
904 cnss_pr_dbg("Modem notifier: event %lu\n", code);
905
906 if (!pci_priv)
907 return NOTIFY_DONE;
908
909 esoc_info = &plat_priv->esoc_info;
910
911 if (code == SUBSYS_AFTER_POWERUP)
912 esoc_info->modem_current_status = 1;
913 else if (code == SUBSYS_BEFORE_SHUTDOWN)
914 esoc_info->modem_current_status = 0;
915 else
916 return NOTIFY_DONE;
917
918 driver_ops = plat_priv->driver_ops;
919 if (!driver_ops || !driver_ops->modem_status)
920 return NOTIFY_DONE;
921
922 driver_ops->modem_status(pci_priv->pci_dev,
923 esoc_info->modem_current_status);
924
925 return NOTIFY_OK;
926}
927
928static int cnss_register_esoc(struct cnss_plat_data *plat_priv)
929{
930 int ret = 0;
931 struct device *dev;
932 struct cnss_esoc_info *esoc_info;
933 struct esoc_desc *esoc_desc;
934 const char *client_desc;
935
936 dev = &plat_priv->plat_dev->dev;
937 esoc_info = &plat_priv->esoc_info;
938
939 esoc_info->notify_modem_status =
940 of_property_read_bool(dev->of_node,
941 "qcom,notify-modem-status");
942
Yue Ma3eb55622018-02-22 12:14:00 -0800943 if (!esoc_info->notify_modem_status)
Yue Ma0317e4a2018-01-10 11:48:32 -0800944 goto out;
945
946 ret = of_property_read_string_index(dev->of_node, "esoc-names", 0,
947 &client_desc);
948 if (ret) {
949 cnss_pr_dbg("esoc-names is not defined in DT, skip!\n");
950 } else {
951 esoc_desc = devm_register_esoc_client(dev, client_desc);
952 if (IS_ERR_OR_NULL(esoc_desc)) {
953 ret = PTR_RET(esoc_desc);
954 cnss_pr_err("Failed to register esoc_desc, err = %d\n",
955 ret);
956 goto out;
957 }
958 esoc_info->esoc_desc = esoc_desc;
959 }
960
961 plat_priv->modem_nb.notifier_call = cnss_modem_notifier_nb;
962 esoc_info->modem_current_status = 0;
963 esoc_info->modem_notify_handler =
964 subsys_notif_register_notifier(esoc_info->esoc_desc ?
965 esoc_info->esoc_desc->name :
966 "modem", &plat_priv->modem_nb);
967 if (IS_ERR(esoc_info->modem_notify_handler)) {
968 ret = PTR_ERR(esoc_info->modem_notify_handler);
969 cnss_pr_err("Failed to register esoc notifier, err = %d\n",
970 ret);
971 goto unreg_esoc;
972 }
973
974 return 0;
975unreg_esoc:
976 if (esoc_info->esoc_desc)
977 devm_unregister_esoc_client(dev, esoc_info->esoc_desc);
978out:
979 return ret;
980}
981
982static void cnss_unregister_esoc(struct cnss_plat_data *plat_priv)
983{
984 struct device *dev;
985 struct cnss_esoc_info *esoc_info;
986
987 dev = &plat_priv->plat_dev->dev;
988 esoc_info = &plat_priv->esoc_info;
989
990 if (esoc_info->notify_modem_status)
991 subsys_notif_unregister_notifier(esoc_info->
992 modem_notify_handler,
993 &plat_priv->modem_nb);
994 if (esoc_info->esoc_desc)
995 devm_unregister_esoc_client(dev, esoc_info->esoc_desc);
996}
997
998static int cnss_qca6174_powerup(struct cnss_plat_data *plat_priv)
999{
1000 int ret = 0;
1001 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1002
1003 if (!pci_priv) {
1004 cnss_pr_err("pci_priv is NULL!\n");
1005 return -ENODEV;
1006 }
1007
1008 ret = cnss_power_on_device(plat_priv);
1009 if (ret) {
1010 cnss_pr_err("Failed to power on device, err = %d\n", ret);
1011 goto out;
1012 }
1013
1014 ret = cnss_resume_pci_link(pci_priv);
1015 if (ret) {
1016 cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
1017 goto power_off;
1018 }
1019
1020 ret = cnss_driver_call_probe(plat_priv);
1021 if (ret)
1022 goto suspend_link;
1023
1024 return 0;
1025suspend_link:
1026 cnss_suspend_pci_link(pci_priv);
1027power_off:
1028 cnss_power_off_device(plat_priv);
1029out:
1030 return ret;
1031}
1032
1033static int cnss_qca6174_shutdown(struct cnss_plat_data *plat_priv)
1034{
1035 int ret = 0;
1036 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1037
1038 if (!pci_priv)
1039 return -ENODEV;
1040
1041 cnss_pm_request_resume(pci_priv);
1042
1043 cnss_driver_call_remove(plat_priv);
1044
1045 cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
1046 CNSS_BUS_WIDTH_NONE);
1047 cnss_pci_set_monitor_wake_intr(pci_priv, false);
1048 cnss_pci_set_auto_suspended(pci_priv, 0);
1049
1050 ret = cnss_suspend_pci_link(pci_priv);
1051 if (ret)
1052 cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
1053
1054 cnss_power_off_device(plat_priv);
1055
1056 clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
1057
1058 return ret;
1059}
1060
1061static void cnss_qca6174_crash_shutdown(struct cnss_plat_data *plat_priv)
1062{
1063 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1064
1065 if (!plat_priv->driver_ops)
1066 return;
1067
1068 plat_priv->driver_ops->crash_shutdown(pci_priv->pci_dev);
1069}
1070
1071static int cnss_qca6290_powerup(struct cnss_plat_data *plat_priv)
1072{
1073 int ret = 0;
1074 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1075 unsigned int timeout;
1076
1077 if (!pci_priv) {
1078 cnss_pr_err("pci_priv is NULL!\n");
1079 return -ENODEV;
1080 }
1081
1082 if (plat_priv->ramdump_info_v2.dump_data_valid ||
1083 test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
1084 cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_DEINIT);
1085 cnss_pci_clear_dump_info(pci_priv);
1086 }
1087
1088 ret = cnss_power_on_device(plat_priv);
1089 if (ret) {
1090 cnss_pr_err("Failed to power on device, err = %d\n", ret);
1091 goto out;
1092 }
1093
1094 ret = cnss_resume_pci_link(pci_priv);
1095 if (ret) {
1096 cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
1097 goto power_off;
1098 }
1099
1100 timeout = cnss_get_qmi_timeout();
1101
1102 ret = cnss_pci_start_mhi(pci_priv);
1103 if (ret) {
1104 cnss_pr_err("Failed to start MHI, err = %d\n", ret);
1105 if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state) &&
1106 !pci_priv->pci_link_down_ind && timeout)
1107 mod_timer(&plat_priv->fw_boot_timer,
1108 jiffies + msecs_to_jiffies(timeout >> 1));
1109 return 0;
1110 }
1111
1112 if (test_bit(USE_CORE_ONLY_FW, &quirks)) {
1113 clear_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state);
1114 clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
1115 return 0;
1116 }
1117
1118 cnss_set_pin_connect_status(plat_priv);
1119
1120 if (qmi_bypass) {
1121 ret = cnss_driver_call_probe(plat_priv);
1122 if (ret)
1123 goto stop_mhi;
1124 } else if (timeout) {
1125 mod_timer(&plat_priv->fw_boot_timer,
1126 jiffies + msecs_to_jiffies(timeout << 1));
1127 }
1128
1129 return 0;
1130
1131stop_mhi:
1132 cnss_pci_stop_mhi(pci_priv);
1133 cnss_suspend_pci_link(pci_priv);
1134power_off:
1135 cnss_power_off_device(plat_priv);
1136out:
1137 return ret;
1138}
1139
1140static int cnss_qca6290_shutdown(struct cnss_plat_data *plat_priv)
1141{
1142 int ret = 0;
1143 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1144
1145 if (!pci_priv)
1146 return -ENODEV;
1147
1148 cnss_pm_request_resume(pci_priv);
1149
1150 cnss_driver_call_remove(plat_priv);
1151
1152 cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
1153 CNSS_BUS_WIDTH_NONE);
1154 cnss_pci_set_monitor_wake_intr(pci_priv, false);
1155 cnss_pci_set_auto_suspended(pci_priv, 0);
1156
1157 cnss_pci_stop_mhi(pci_priv);
1158
1159 ret = cnss_suspend_pci_link(pci_priv);
1160 if (ret)
1161 cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
1162
1163 cnss_power_off_device(plat_priv);
1164
1165 clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
1166 clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state);
1167 clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
1168
1169 return ret;
1170}
1171
1172static void cnss_qca6290_crash_shutdown(struct cnss_plat_data *plat_priv)
1173{
1174 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
Yue Ma0317e4a2018-01-10 11:48:32 -08001175
1176 cnss_pr_dbg("Crash shutdown with driver_state 0x%lx\n",
1177 plat_priv->driver_state);
1178
1179 if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) ||
1180 test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
Yue Ma3eb55622018-02-22 12:14:00 -08001181 test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
1182 cnss_pr_dbg("Ignore crash shutdown\n");
Yue Ma0317e4a2018-01-10 11:48:32 -08001183 return;
1184 }
1185
Yue Ma3eb55622018-02-22 12:14:00 -08001186 cnss_pci_collect_dump_info(pci_priv, true);
Yue Ma0317e4a2018-01-10 11:48:32 -08001187}
1188
1189static int cnss_powerup(struct cnss_plat_data *plat_priv)
1190{
1191 int ret;
1192
1193 switch (plat_priv->device_id) {
1194 case QCA6174_DEVICE_ID:
1195 ret = cnss_qca6174_powerup(plat_priv);
1196 break;
1197 case QCA6290_EMULATION_DEVICE_ID:
1198 case QCA6290_DEVICE_ID:
1199 ret = cnss_qca6290_powerup(plat_priv);
1200 break;
1201 default:
1202 cnss_pr_err("Unknown device_id found: 0x%lx\n",
1203 plat_priv->device_id);
1204 ret = -ENODEV;
1205 }
1206
1207 return ret;
1208}
1209
1210static int cnss_shutdown(struct cnss_plat_data *plat_priv)
1211{
1212 int ret;
1213
1214 switch (plat_priv->device_id) {
1215 case QCA6174_DEVICE_ID:
1216 ret = cnss_qca6174_shutdown(plat_priv);
1217 break;
1218 case QCA6290_EMULATION_DEVICE_ID:
1219 case QCA6290_DEVICE_ID:
1220 ret = cnss_qca6290_shutdown(plat_priv);
1221 break;
1222 default:
1223 cnss_pr_err("Unknown device_id found: 0x%lx\n",
1224 plat_priv->device_id);
1225 ret = -ENODEV;
1226 }
1227
1228 return ret;
1229}
1230
1231static int cnss_subsys_powerup(const struct subsys_desc *subsys_desc)
1232{
1233 struct cnss_plat_data *plat_priv;
1234
1235 if (!subsys_desc->dev) {
1236 cnss_pr_err("dev from subsys_desc is NULL\n");
1237 return -ENODEV;
1238 }
1239
1240 plat_priv = dev_get_drvdata(subsys_desc->dev);
1241 if (!plat_priv) {
1242 cnss_pr_err("plat_priv is NULL\n");
1243 return -ENODEV;
1244 }
1245
1246 if (!plat_priv->driver_state) {
1247 cnss_pr_dbg("Powerup is ignored\n");
1248 return 0;
1249 }
1250
1251 return cnss_powerup(plat_priv);
1252}
1253
1254static int cnss_subsys_shutdown(const struct subsys_desc *subsys_desc,
1255 bool force_stop)
1256{
1257 struct cnss_plat_data *plat_priv;
1258
1259 if (!subsys_desc->dev) {
1260 cnss_pr_err("dev from subsys_desc is NULL\n");
1261 return -ENODEV;
1262 }
1263
1264 plat_priv = dev_get_drvdata(subsys_desc->dev);
1265 if (!plat_priv) {
1266 cnss_pr_err("plat_priv is NULL\n");
1267 return -ENODEV;
1268 }
1269
1270 if (!plat_priv->driver_state) {
1271 cnss_pr_dbg("shutdown is ignored\n");
1272 return 0;
1273 }
1274
1275 return cnss_shutdown(plat_priv);
1276}
1277
1278static int cnss_qca6290_ramdump(struct cnss_plat_data *plat_priv)
1279{
1280 struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2;
1281 struct cnss_dump_data *dump_data = &info_v2->dump_data;
1282 struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr;
1283 struct ramdump_segment *ramdump_segs, *s;
1284 int i, ret = 0;
1285
1286 if (!info_v2->dump_data_valid ||
1287 dump_data->nentries == 0)
1288 return 0;
1289
1290 ramdump_segs = kcalloc(dump_data->nentries,
1291 sizeof(*ramdump_segs),
1292 GFP_KERNEL);
1293 if (!ramdump_segs)
1294 return -ENOMEM;
1295
1296 s = ramdump_segs;
1297 for (i = 0; i < dump_data->nentries; i++) {
1298 s->address = dump_seg->address;
1299 s->v_address = dump_seg->v_address;
1300 s->size = dump_seg->size;
1301 s++;
1302 dump_seg++;
1303 }
1304
1305 ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs,
1306 dump_data->nentries);
1307 kfree(ramdump_segs);
1308
1309 cnss_pci_set_mhi_state(plat_priv->bus_priv, CNSS_MHI_DEINIT);
1310 cnss_pci_clear_dump_info(plat_priv->bus_priv);
1311
1312 return ret;
1313}
1314
1315static int cnss_qca6174_ramdump(struct cnss_plat_data *plat_priv)
1316{
1317 int ret = 0;
1318 struct cnss_ramdump_info *ramdump_info;
1319 struct ramdump_segment segment;
1320
1321 ramdump_info = &plat_priv->ramdump_info;
1322 if (!ramdump_info->ramdump_size)
1323 return -EINVAL;
1324
1325 memset(&segment, 0, sizeof(segment));
1326 segment.v_address = ramdump_info->ramdump_va;
1327 segment.size = ramdump_info->ramdump_size;
1328 ret = do_ramdump(ramdump_info->ramdump_dev, &segment, 1);
1329
1330 return ret;
1331}
1332
1333static int cnss_subsys_ramdump(int enable,
1334 const struct subsys_desc *subsys_desc)
1335{
1336 int ret = 0;
1337 struct cnss_plat_data *plat_priv = dev_get_drvdata(subsys_desc->dev);
1338
1339 if (!plat_priv) {
1340 cnss_pr_err("plat_priv is NULL!\n");
1341 return -ENODEV;
1342 }
1343
1344 if (!enable)
1345 return 0;
1346
1347 switch (plat_priv->device_id) {
1348 case QCA6174_DEVICE_ID:
1349 ret = cnss_qca6174_ramdump(plat_priv);
1350 break;
1351 case QCA6290_EMULATION_DEVICE_ID:
1352 case QCA6290_DEVICE_ID:
1353 ret = cnss_qca6290_ramdump(plat_priv);
1354 break;
1355 default:
1356 cnss_pr_err("Unknown device_id found: 0x%lx\n",
1357 plat_priv->device_id);
1358 ret = -ENODEV;
1359 }
1360
1361 return ret;
1362}
1363
1364void *cnss_get_virt_ramdump_mem(struct device *dev, unsigned long *size)
1365{
1366 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1367 struct cnss_ramdump_info *ramdump_info;
1368
1369 if (!plat_priv)
1370 return NULL;
1371
1372 ramdump_info = &plat_priv->ramdump_info;
1373 *size = ramdump_info->ramdump_size;
1374
1375 return ramdump_info->ramdump_va;
1376}
1377EXPORT_SYMBOL(cnss_get_virt_ramdump_mem);
1378
1379void cnss_device_crashed(struct device *dev)
1380{
1381 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1382 struct cnss_subsys_info *subsys_info;
1383
1384 if (!plat_priv)
1385 return;
1386
1387 subsys_info = &plat_priv->subsys_info;
1388 if (subsys_info->subsys_device) {
1389 set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
1390 subsys_set_crash_status(subsys_info->subsys_device, true);
1391 subsystem_restart_dev(subsys_info->subsys_device);
1392 }
1393}
1394EXPORT_SYMBOL(cnss_device_crashed);
1395
1396static void cnss_subsys_crash_shutdown(const struct subsys_desc *subsys_desc)
1397{
1398 struct cnss_plat_data *plat_priv = dev_get_drvdata(subsys_desc->dev);
1399
1400 if (!plat_priv) {
1401 cnss_pr_err("plat_priv is NULL!\n");
1402 return;
1403 }
1404
1405 switch (plat_priv->device_id) {
1406 case QCA6174_DEVICE_ID:
1407 cnss_qca6174_crash_shutdown(plat_priv);
1408 break;
1409 case QCA6290_EMULATION_DEVICE_ID:
1410 case QCA6290_DEVICE_ID:
1411 cnss_qca6290_crash_shutdown(plat_priv);
1412 break;
1413 default:
1414 cnss_pr_err("Unknown device_id found: 0x%lx\n",
1415 plat_priv->device_id);
1416 }
1417}
1418
1419static const char *cnss_recovery_reason_to_str(enum cnss_recovery_reason reason)
1420{
1421 switch (reason) {
1422 case CNSS_REASON_DEFAULT:
1423 return "DEFAULT";
1424 case CNSS_REASON_LINK_DOWN:
1425 return "LINK_DOWN";
1426 case CNSS_REASON_RDDM:
1427 return "RDDM";
1428 case CNSS_REASON_TIMEOUT:
1429 return "TIMEOUT";
1430 }
1431
1432 return "UNKNOWN";
1433};
1434
1435static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
1436 enum cnss_recovery_reason reason)
1437{
1438 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1439 struct cnss_subsys_info *subsys_info =
1440 &plat_priv->subsys_info;
Yue Ma0317e4a2018-01-10 11:48:32 -08001441
1442 plat_priv->recovery_count++;
1443
1444 if (plat_priv->device_id == QCA6174_DEVICE_ID)
1445 goto self_recovery;
1446
1447 if (plat_priv->driver_ops &&
1448 test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state))
1449 plat_priv->driver_ops->update_status(pci_priv->pci_dev,
1450 CNSS_RECOVERY);
1451
1452 if (test_bit(SKIP_RECOVERY, &quirks)) {
1453 cnss_pr_dbg("Skip device recovery\n");
1454 return 0;
1455 }
1456
1457 switch (reason) {
1458 case CNSS_REASON_LINK_DOWN:
1459 if (test_bit(LINK_DOWN_SELF_RECOVERY, &quirks))
1460 goto self_recovery;
1461 break;
1462 case CNSS_REASON_RDDM:
1463 clear_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state);
Yue Ma3eb55622018-02-22 12:14:00 -08001464 cnss_pci_collect_dump_info(pci_priv, false);
Yue Ma0317e4a2018-01-10 11:48:32 -08001465 break;
1466 case CNSS_REASON_DEFAULT:
1467 case CNSS_REASON_TIMEOUT:
1468 break;
1469 default:
1470 cnss_pr_err("Unsupported recovery reason: %s(%d)\n",
1471 cnss_recovery_reason_to_str(reason), reason);
1472 break;
1473 }
1474
1475 if (!subsys_info->subsys_device)
1476 return 0;
1477
1478 subsys_set_crash_status(subsys_info->subsys_device, true);
1479 subsystem_restart_dev(subsys_info->subsys_device);
1480
1481 return 0;
1482
1483self_recovery:
1484 cnss_shutdown(plat_priv);
1485 cnss_powerup(plat_priv);
1486
1487 return 0;
1488}
1489
1490static int cnss_driver_recovery_hdlr(struct cnss_plat_data *plat_priv,
1491 void *data)
1492{
1493 struct cnss_recovery_data *recovery_data = data;
1494 int ret = 0;
1495
1496 cnss_pr_dbg("Driver recovery is triggered with reason: %s(%d)\n",
1497 cnss_recovery_reason_to_str(recovery_data->reason),
1498 recovery_data->reason);
1499
1500 if (!plat_priv->driver_state) {
1501 cnss_pr_err("Improper driver state, ignore recovery\n");
1502 ret = -EINVAL;
1503 goto out;
1504 }
1505
1506 if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
1507 cnss_pr_err("Recovery is already in progress\n");
1508 ret = -EINVAL;
1509 goto out;
1510 }
1511
1512 if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
1513 cnss_pr_err("Driver unload is in progress, ignore recovery\n");
1514 ret = -EINVAL;
1515 goto out;
1516 }
1517
1518 switch (plat_priv->device_id) {
1519 case QCA6174_DEVICE_ID:
1520 if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) {
1521 cnss_pr_err("Driver load is in progress, ignore recovery\n");
1522 ret = -EINVAL;
1523 goto out;
1524 }
1525 break;
1526 default:
1527 if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
1528 set_bit(CNSS_FW_BOOT_RECOVERY,
1529 &plat_priv->driver_state);
1530 } else if (test_bit(CNSS_DRIVER_LOADING,
1531 &plat_priv->driver_state)) {
1532 cnss_pr_err("Driver probe is in progress, ignore recovery\n");
1533 ret = -EINVAL;
1534 goto out;
1535 }
1536 break;
1537 }
1538
1539 set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
1540 ret = cnss_do_recovery(plat_priv, recovery_data->reason);
1541
1542out:
1543 kfree(data);
1544 return ret;
1545}
1546
1547int cnss_self_recovery(struct device *dev,
1548 enum cnss_recovery_reason reason)
1549{
1550 cnss_schedule_recovery(dev, reason);
1551 return 0;
1552}
1553EXPORT_SYMBOL(cnss_self_recovery);
1554
1555void cnss_schedule_recovery(struct device *dev,
1556 enum cnss_recovery_reason reason)
1557{
1558 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1559 struct cnss_recovery_data *data;
1560 int gfp = GFP_KERNEL;
1561
1562 if (in_interrupt() || irqs_disabled())
1563 gfp = GFP_ATOMIC;
1564
1565 data = kzalloc(sizeof(*data), gfp);
1566 if (!data)
1567 return;
1568
1569 data->reason = reason;
1570 cnss_driver_event_post(plat_priv,
1571 CNSS_DRIVER_EVENT_RECOVERY,
1572 0, data);
1573}
1574EXPORT_SYMBOL(cnss_schedule_recovery);
1575
1576static int cnss_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv)
1577{
1578 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1579 int ret;
1580
1581 ret = cnss_pci_set_mhi_state(plat_priv->bus_priv,
1582 CNSS_MHI_TRIGGER_RDDM);
1583 if (ret) {
1584 cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret);
1585 cnss_schedule_recovery(&pci_priv->pci_dev->dev,
1586 CNSS_REASON_DEFAULT);
1587 return 0;
1588 }
1589
1590 if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) {
1591 mod_timer(&plat_priv->fw_boot_timer,
1592 jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT));
1593 }
1594
1595 return 0;
1596}
1597
1598int cnss_force_fw_assert(struct device *dev)
1599{
1600 struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
1601
1602 if (!plat_priv) {
1603 cnss_pr_err("plat_priv is NULL\n");
1604 return -ENODEV;
1605 }
1606
1607 if (plat_priv->device_id == QCA6174_DEVICE_ID) {
1608 cnss_pr_info("Forced FW assert is not supported\n");
1609 return -EOPNOTSUPP;
1610 }
1611
1612 if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
1613 cnss_pr_info("Recovery is already in progress, ignore forced FW assert\n");
1614 return 0;
1615 }
1616
1617 cnss_driver_event_post(plat_priv,
1618 CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
1619 0, NULL);
1620
1621 return 0;
1622}
1623EXPORT_SYMBOL(cnss_force_fw_assert);
1624
1625void fw_boot_timeout(unsigned long data)
1626{
1627 struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data;
1628 struct cnss_pci_data *pci_priv = plat_priv->bus_priv;
1629
1630 cnss_pr_err("Timeout waiting for FW ready indication!\n");
1631
1632 cnss_schedule_recovery(&pci_priv->pci_dev->dev,
1633 CNSS_REASON_TIMEOUT);
1634}
1635
1636static int cnss_register_driver_hdlr(struct cnss_plat_data *plat_priv,
1637 void *data)
1638{
1639 int ret = 0;
1640
1641 set_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
1642 plat_priv->driver_ops = data;
1643
1644 ret = cnss_powerup(plat_priv);
1645 if (ret) {
1646 clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
1647 plat_priv->driver_ops = NULL;
1648 }
1649
1650 return ret;
1651}
1652
1653static int cnss_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
1654{
1655 set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
1656 cnss_shutdown(plat_priv);
1657 plat_priv->driver_ops = NULL;
1658
1659 return 0;
1660}
1661
1662static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
1663{
1664 int ret = 0;
1665
1666 set_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
1667 ret = cnss_powerup(plat_priv);
1668 if (ret)
1669 clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
1670
1671 return ret;
1672}
1673
1674static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
1675{
1676 cnss_wlfw_wlan_mode_send_sync(plat_priv, QMI_WLFW_OFF_V01);
1677 cnss_shutdown(plat_priv);
1678 clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
1679
1680 return 0;
1681}
1682
1683static int cnss_power_up_hdlr(struct cnss_plat_data *plat_priv)
1684{
1685 return cnss_powerup(plat_priv);
1686}
1687
1688static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv)
1689{
1690 cnss_shutdown(plat_priv);
1691
1692 return 0;
1693}
1694
1695static void cnss_driver_event_work(struct work_struct *work)
1696{
1697 struct cnss_plat_data *plat_priv =
1698 container_of(work, struct cnss_plat_data, event_work);
1699 struct cnss_driver_event *event;
1700 unsigned long flags;
1701 int ret = 0;
1702
1703 if (!plat_priv) {
1704 cnss_pr_err("plat_priv is NULL!\n");
1705 return;
1706 }
1707
1708 cnss_pm_stay_awake(plat_priv);
1709
1710 spin_lock_irqsave(&plat_priv->event_lock, flags);
1711
1712 while (!list_empty(&plat_priv->event_list)) {
1713 event = list_first_entry(&plat_priv->event_list,
1714 struct cnss_driver_event, list);
1715 list_del(&event->list);
1716 spin_unlock_irqrestore(&plat_priv->event_lock, flags);
1717
1718 cnss_pr_dbg("Processing driver event: %s%s(%d), state: 0x%lx\n",
1719 cnss_driver_event_to_str(event->type),
1720 event->sync ? "-sync" : "", event->type,
1721 plat_priv->driver_state);
1722
1723 switch (event->type) {
1724 case CNSS_DRIVER_EVENT_SERVER_ARRIVE:
1725 ret = cnss_wlfw_server_arrive(plat_priv);
1726 break;
1727 case CNSS_DRIVER_EVENT_SERVER_EXIT:
1728 ret = cnss_wlfw_server_exit(plat_priv);
1729 break;
1730 case CNSS_DRIVER_EVENT_REQUEST_MEM:
1731 ret = cnss_pci_alloc_fw_mem(plat_priv->bus_priv);
1732 if (ret)
1733 break;
1734 ret = cnss_wlfw_respond_mem_send_sync(plat_priv);
1735 break;
1736 case CNSS_DRIVER_EVENT_FW_MEM_READY:
1737 ret = cnss_fw_mem_ready_hdlr(plat_priv);
1738 break;
1739 case CNSS_DRIVER_EVENT_FW_READY:
1740 ret = cnss_fw_ready_hdlr(plat_priv);
1741 break;
1742 case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START:
1743 ret = cnss_cold_boot_cal_start_hdlr(plat_priv);
1744 break;
1745 case CNSS_DRIVER_EVENT_COLD_BOOT_CAL_DONE:
1746 ret = cnss_cold_boot_cal_done_hdlr(plat_priv);
1747 break;
1748 case CNSS_DRIVER_EVENT_REGISTER_DRIVER:
1749 ret = cnss_register_driver_hdlr(plat_priv,
1750 event->data);
1751 break;
1752 case CNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
1753 ret = cnss_unregister_driver_hdlr(plat_priv);
1754 break;
1755 case CNSS_DRIVER_EVENT_RECOVERY:
1756 ret = cnss_driver_recovery_hdlr(plat_priv,
1757 event->data);
1758 break;
1759 case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
1760 ret = cnss_force_fw_assert_hdlr(plat_priv);
1761 break;
1762 case CNSS_DRIVER_EVENT_POWER_UP:
1763 ret = cnss_power_up_hdlr(plat_priv);
1764 break;
1765 case CNSS_DRIVER_EVENT_POWER_DOWN:
1766 ret = cnss_power_down_hdlr(plat_priv);
1767 break;
1768 default:
1769 cnss_pr_err("Invalid driver event type: %d",
1770 event->type);
1771 kfree(event);
1772 spin_lock_irqsave(&plat_priv->event_lock, flags);
1773 continue;
1774 }
1775
1776 spin_lock_irqsave(&plat_priv->event_lock, flags);
1777 if (event->sync) {
1778 event->ret = ret;
1779 complete(&event->complete);
1780 continue;
1781 }
1782 spin_unlock_irqrestore(&plat_priv->event_lock, flags);
1783
1784 kfree(event);
1785
1786 spin_lock_irqsave(&plat_priv->event_lock, flags);
1787 }
1788 spin_unlock_irqrestore(&plat_priv->event_lock, flags);
1789
1790 cnss_pm_relax(plat_priv);
1791}
1792
1793int cnss_register_subsys(struct cnss_plat_data *plat_priv)
1794{
1795 int ret = 0;
1796 struct cnss_subsys_info *subsys_info;
1797
1798 subsys_info = &plat_priv->subsys_info;
1799
1800 switch (plat_priv->device_id) {
1801 case QCA6174_DEVICE_ID:
1802 subsys_info->subsys_desc.name = "AR6320";
1803 break;
1804 case QCA6290_EMULATION_DEVICE_ID:
1805 case QCA6290_DEVICE_ID:
1806 subsys_info->subsys_desc.name = "QCA6290";
1807 break;
1808 default:
1809 cnss_pr_err("Unknown device ID: 0x%lx\n", plat_priv->device_id);
1810 ret = -ENODEV;
1811 goto out;
1812 }
1813
1814 subsys_info->subsys_desc.owner = THIS_MODULE;
1815 subsys_info->subsys_desc.powerup = cnss_subsys_powerup;
1816 subsys_info->subsys_desc.shutdown = cnss_subsys_shutdown;
1817 subsys_info->subsys_desc.ramdump = cnss_subsys_ramdump;
1818 subsys_info->subsys_desc.crash_shutdown = cnss_subsys_crash_shutdown;
1819 subsys_info->subsys_desc.dev = &plat_priv->plat_dev->dev;
1820
1821 subsys_info->subsys_device = subsys_register(&subsys_info->subsys_desc);
1822 if (IS_ERR(subsys_info->subsys_device)) {
1823 ret = PTR_ERR(subsys_info->subsys_device);
1824 cnss_pr_err("Failed to register subsys, err = %d\n", ret);
1825 goto out;
1826 }
1827
1828 subsys_info->subsys_handle =
1829 subsystem_get(subsys_info->subsys_desc.name);
1830 if (!subsys_info->subsys_handle) {
1831 cnss_pr_err("Failed to get subsys_handle!\n");
1832 ret = -EINVAL;
1833 goto unregister_subsys;
1834 } else if (IS_ERR(subsys_info->subsys_handle)) {
1835 ret = PTR_ERR(subsys_info->subsys_handle);
1836 cnss_pr_err("Failed to do subsystem_get, err = %d\n", ret);
1837 goto unregister_subsys;
1838 }
1839
1840 return 0;
1841
1842unregister_subsys:
1843 subsys_unregister(subsys_info->subsys_device);
1844out:
1845 return ret;
1846}
1847
1848void cnss_unregister_subsys(struct cnss_plat_data *plat_priv)
1849{
1850 struct cnss_subsys_info *subsys_info;
1851
1852 subsys_info = &plat_priv->subsys_info;
1853 subsystem_put(subsys_info->subsys_handle);
1854 subsys_unregister(subsys_info->subsys_device);
1855}
1856
1857static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv)
1858{
1859 struct cnss_ramdump_info *ramdump_info;
1860 struct msm_dump_entry dump_entry;
1861
1862 ramdump_info = &plat_priv->ramdump_info;
1863 ramdump_info->dump_data.addr = ramdump_info->ramdump_pa;
1864 ramdump_info->dump_data.len = ramdump_info->ramdump_size;
1865 ramdump_info->dump_data.version = CNSS_DUMP_FORMAT_VER;
1866 ramdump_info->dump_data.magic = CNSS_DUMP_MAGIC_VER_V2;
1867 strlcpy(ramdump_info->dump_data.name, CNSS_DUMP_NAME,
1868 sizeof(ramdump_info->dump_data.name));
1869 dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN;
1870 dump_entry.addr = virt_to_phys(&ramdump_info->dump_data);
1871
1872 return msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry);
1873}
1874
1875static int cnss_qca6174_register_ramdump(struct cnss_plat_data *plat_priv)
1876{
1877 int ret = 0;
1878 struct device *dev;
1879 struct cnss_subsys_info *subsys_info;
1880 struct cnss_ramdump_info *ramdump_info;
1881 u32 ramdump_size = 0;
1882
1883 dev = &plat_priv->plat_dev->dev;
1884 subsys_info = &plat_priv->subsys_info;
1885 ramdump_info = &plat_priv->ramdump_info;
1886
1887 if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
1888 &ramdump_size) == 0) {
1889 ramdump_info->ramdump_va = dma_alloc_coherent(dev, ramdump_size,
1890 &ramdump_info->ramdump_pa, GFP_KERNEL);
1891
1892 if (ramdump_info->ramdump_va)
1893 ramdump_info->ramdump_size = ramdump_size;
1894 }
1895
1896 cnss_pr_dbg("ramdump va: %pK, pa: %pa\n",
1897 ramdump_info->ramdump_va, &ramdump_info->ramdump_pa);
1898
1899 if (ramdump_info->ramdump_size == 0) {
1900 cnss_pr_info("Ramdump will not be collected");
1901 goto out;
1902 }
1903
1904 ret = cnss_init_dump_entry(plat_priv);
1905 if (ret) {
1906 cnss_pr_err("Failed to setup dump table, err = %d\n", ret);
1907 goto free_ramdump;
1908 }
1909
1910 ramdump_info->ramdump_dev = create_ramdump_device(
1911 subsys_info->subsys_desc.name, subsys_info->subsys_desc.dev);
1912 if (!ramdump_info->ramdump_dev) {
1913 cnss_pr_err("Failed to create ramdump device!");
1914 ret = -ENOMEM;
1915 goto free_ramdump;
1916 }
1917
1918 return 0;
1919free_ramdump:
1920 dma_free_coherent(dev, ramdump_info->ramdump_size,
1921 ramdump_info->ramdump_va, ramdump_info->ramdump_pa);
1922out:
1923 return ret;
1924}
1925
1926static void cnss_qca6174_unregister_ramdump(struct cnss_plat_data *plat_priv)
1927{
1928 struct device *dev;
1929 struct cnss_ramdump_info *ramdump_info;
1930
1931 dev = &plat_priv->plat_dev->dev;
1932 ramdump_info = &plat_priv->ramdump_info;
1933
1934 if (ramdump_info->ramdump_dev)
1935 destroy_ramdump_device(ramdump_info->ramdump_dev);
1936
1937 if (ramdump_info->ramdump_va)
1938 dma_free_coherent(dev, ramdump_info->ramdump_size,
1939 ramdump_info->ramdump_va,
1940 ramdump_info->ramdump_pa);
1941}
1942
1943static int cnss_qca6290_register_ramdump(struct cnss_plat_data *plat_priv)
1944{
1945 int ret = 0;
1946 struct cnss_subsys_info *subsys_info;
1947 struct cnss_ramdump_info_v2 *info_v2;
1948 struct cnss_dump_data *dump_data;
1949 struct msm_dump_entry dump_entry;
1950 struct device *dev = &plat_priv->plat_dev->dev;
1951 u32 ramdump_size = 0;
1952
1953 subsys_info = &plat_priv->subsys_info;
1954 info_v2 = &plat_priv->ramdump_info_v2;
1955 dump_data = &info_v2->dump_data;
1956
1957 if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
1958 &ramdump_size) == 0)
1959 info_v2->ramdump_size = ramdump_size;
1960
1961 cnss_pr_dbg("Ramdump size 0x%lx\n", info_v2->ramdump_size);
1962
1963 info_v2->dump_data_vaddr = kzalloc(CNSS_DUMP_DESC_SIZE, GFP_KERNEL);
1964 if (!info_v2->dump_data_vaddr)
1965 return -ENOMEM;
1966
1967 dump_data->paddr = virt_to_phys(info_v2->dump_data_vaddr);
1968 dump_data->version = CNSS_DUMP_FORMAT_VER_V2;
1969 dump_data->magic = CNSS_DUMP_MAGIC_VER_V2;
1970 dump_data->seg_version = CNSS_DUMP_SEG_VER;
1971 strlcpy(dump_data->name, CNSS_DUMP_NAME,
1972 sizeof(dump_data->name));
1973 dump_entry.id = MSM_DUMP_DATA_CNSS_WLAN;
1974 dump_entry.addr = virt_to_phys(dump_data);
1975
1976 ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, &dump_entry);
1977 if (ret) {
1978 cnss_pr_err("Failed to setup dump table, err = %d\n", ret);
1979 goto free_ramdump;
1980 }
1981
1982 info_v2->ramdump_dev =
1983 create_ramdump_device(subsys_info->subsys_desc.name,
1984 subsys_info->subsys_desc.dev);
1985 if (!info_v2->ramdump_dev) {
1986 cnss_pr_err("Failed to create ramdump device!\n");
1987 ret = -ENOMEM;
1988 goto free_ramdump;
1989 }
1990
1991 return 0;
1992
1993free_ramdump:
1994 kfree(info_v2->dump_data_vaddr);
1995 info_v2->dump_data_vaddr = NULL;
1996 return ret;
1997}
1998
1999static void cnss_qca6290_unregister_ramdump(struct cnss_plat_data *plat_priv)
2000{
2001 struct cnss_ramdump_info_v2 *info_v2;
2002
2003 info_v2 = &plat_priv->ramdump_info_v2;
2004
2005 if (info_v2->ramdump_dev)
2006 destroy_ramdump_device(info_v2->ramdump_dev);
2007
2008 kfree(info_v2->dump_data_vaddr);
2009 info_v2->dump_data_vaddr = NULL;
2010 info_v2->dump_data_valid = false;
2011}
2012
2013int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
2014{
2015 int ret = 0;
2016
2017 switch (plat_priv->device_id) {
2018 case QCA6174_DEVICE_ID:
2019 ret = cnss_qca6174_register_ramdump(plat_priv);
2020 break;
2021 case QCA6290_EMULATION_DEVICE_ID:
2022 case QCA6290_DEVICE_ID:
2023 ret = cnss_qca6290_register_ramdump(plat_priv);
2024 break;
2025 default:
2026 cnss_pr_err("Unknown device ID: 0x%lx\n", plat_priv->device_id);
2027 ret = -ENODEV;
2028 break;
2029 }
2030 return ret;
2031}
2032
2033void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
2034{
2035 switch (plat_priv->device_id) {
2036 case QCA6174_DEVICE_ID:
2037 cnss_qca6174_unregister_ramdump(plat_priv);
2038 break;
2039 case QCA6290_EMULATION_DEVICE_ID:
2040 case QCA6290_DEVICE_ID:
2041 cnss_qca6290_unregister_ramdump(plat_priv);
2042 break;
2043 default:
2044 cnss_pr_err("Unknown device ID: 0x%lx\n", plat_priv->device_id);
2045 break;
2046 }
2047}
2048
2049static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
2050{
2051 int ret = 0;
2052 struct cnss_bus_bw_info *bus_bw_info;
2053
2054 bus_bw_info = &plat_priv->bus_bw_info;
2055
2056 bus_bw_info->bus_scale_table =
2057 msm_bus_cl_get_pdata(plat_priv->plat_dev);
2058 if (bus_bw_info->bus_scale_table) {
2059 bus_bw_info->bus_client =
2060 msm_bus_scale_register_client(
2061 bus_bw_info->bus_scale_table);
2062 if (!bus_bw_info->bus_client) {
2063 cnss_pr_err("Failed to register bus scale client!\n");
2064 ret = -EINVAL;
2065 goto out;
2066 }
2067 }
2068
2069 return 0;
2070out:
2071 return ret;
2072}
2073
2074static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv)
2075{
2076 struct cnss_bus_bw_info *bus_bw_info;
2077
2078 bus_bw_info = &plat_priv->bus_bw_info;
2079
2080 if (bus_bw_info->bus_client)
2081 msm_bus_scale_unregister_client(bus_bw_info->bus_client);
2082}
2083
2084static ssize_t cnss_fs_ready_store(struct device *dev,
2085 struct device_attribute *attr,
2086 const char *buf,
2087 size_t count)
2088{
2089 int fs_ready = 0;
2090 struct cnss_plat_data *plat_priv = dev_get_drvdata(dev);
2091
2092 if (sscanf(buf, "%du", &fs_ready) != 1)
2093 return -EINVAL;
2094
2095 cnss_pr_dbg("File system is ready, fs_ready is %d, count is %zu\n",
2096 fs_ready, count);
2097
2098 if (qmi_bypass) {
2099 cnss_pr_dbg("QMI is bypassed.\n");
2100 return count;
2101 }
2102
2103 if (!plat_priv) {
2104 cnss_pr_err("plat_priv is NULL!\n");
2105 return count;
2106 }
2107
2108 switch (plat_priv->device_id) {
2109 case QCA6290_EMULATION_DEVICE_ID:
2110 case QCA6290_DEVICE_ID:
2111 break;
2112 default:
2113 cnss_pr_err("Not supported for device ID 0x%lx\n",
2114 plat_priv->device_id);
2115 return count;
2116 }
2117
2118 if (fs_ready == FILE_SYSTEM_READY) {
2119 cnss_driver_event_post(plat_priv,
2120 CNSS_DRIVER_EVENT_COLD_BOOT_CAL_START,
2121 CNSS_EVENT_SYNC, NULL);
2122 }
2123
2124 return count;
2125}
2126
2127static DEVICE_ATTR(fs_ready, 0220, NULL, cnss_fs_ready_store);
2128
2129static int cnss_create_sysfs(struct cnss_plat_data *plat_priv)
2130{
2131 int ret = 0;
2132
2133 ret = device_create_file(&plat_priv->plat_dev->dev, &dev_attr_fs_ready);
2134 if (ret) {
2135 cnss_pr_err("Failed to create device file, err = %d\n", ret);
2136 goto out;
2137 }
2138
2139 return 0;
2140out:
2141 return ret;
2142}
2143
2144static void cnss_remove_sysfs(struct cnss_plat_data *plat_priv)
2145{
2146 device_remove_file(&plat_priv->plat_dev->dev, &dev_attr_fs_ready);
2147}
2148
2149static int cnss_event_work_init(struct cnss_plat_data *plat_priv)
2150{
2151 spin_lock_init(&plat_priv->event_lock);
2152 plat_priv->event_wq = alloc_workqueue("cnss_driver_event",
2153 WQ_UNBOUND, 1);
2154 if (!plat_priv->event_wq) {
2155 cnss_pr_err("Failed to create event workqueue!\n");
2156 return -EFAULT;
2157 }
2158
2159 INIT_WORK(&plat_priv->event_work, cnss_driver_event_work);
2160 INIT_LIST_HEAD(&plat_priv->event_list);
2161
2162 return 0;
2163}
2164
2165static void cnss_event_work_deinit(struct cnss_plat_data *plat_priv)
2166{
2167 destroy_workqueue(plat_priv->event_wq);
2168}
2169
2170static const struct platform_device_id cnss_platform_id_table[] = {
2171 { .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, },
2172 { .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
2173};
2174
2175static const struct of_device_id cnss_of_match_table[] = {
2176 {
2177 .compatible = "qcom,cnss",
2178 .data = (void *)&cnss_platform_id_table[0]},
2179 {
2180 .compatible = "qcom,cnss-qca6290",
2181 .data = (void *)&cnss_platform_id_table[1]},
2182 { },
2183};
2184MODULE_DEVICE_TABLE(of, cnss_of_match_table);
2185
2186static int cnss_probe(struct platform_device *plat_dev)
2187{
2188 int ret = 0;
2189 struct cnss_plat_data *plat_priv;
2190 const struct of_device_id *of_id;
2191 const struct platform_device_id *device_id;
2192
2193 if (cnss_get_plat_priv(plat_dev)) {
2194 cnss_pr_err("Driver is already initialized!\n");
2195 ret = -EEXIST;
2196 goto out;
2197 }
2198
2199 of_id = of_match_device(cnss_of_match_table, &plat_dev->dev);
2200 if (!of_id || !of_id->data) {
2201 cnss_pr_err("Failed to find of match device!\n");
2202 ret = -ENODEV;
2203 goto out;
2204 }
2205
2206 device_id = of_id->data;
2207
2208 plat_priv = devm_kzalloc(&plat_dev->dev, sizeof(*plat_priv),
2209 GFP_KERNEL);
2210 if (!plat_priv) {
2211 ret = -ENOMEM;
2212 goto out;
2213 }
2214
2215 plat_priv->plat_dev = plat_dev;
2216 plat_priv->device_id = device_id->driver_data;
2217 cnss_set_plat_priv(plat_dev, plat_priv);
2218 platform_set_drvdata(plat_dev, plat_priv);
2219
2220 ret = cnss_get_resources(plat_priv);
2221 if (ret)
2222 goto reset_ctx;
2223
2224 if (!test_bit(SKIP_DEVICE_BOOT, &quirks)) {
2225 ret = cnss_power_on_device(plat_priv);
2226 if (ret)
2227 goto free_res;
2228
2229 ret = cnss_pci_init(plat_priv);
2230 if (ret)
2231 goto power_off;
2232 }
2233
2234 ret = cnss_register_esoc(plat_priv);
2235 if (ret)
2236 goto deinit_pci;
2237
2238 ret = cnss_register_bus_scale(plat_priv);
2239 if (ret)
2240 goto unreg_esoc;
2241
2242 ret = cnss_create_sysfs(plat_priv);
2243 if (ret)
2244 goto unreg_bus_scale;
2245
2246 ret = cnss_event_work_init(plat_priv);
2247 if (ret)
2248 goto remove_sysfs;
2249
2250 ret = cnss_qmi_init(plat_priv);
2251 if (ret)
2252 goto deinit_event_work;
2253
2254 ret = cnss_debugfs_create(plat_priv);
2255 if (ret)
2256 goto deinit_qmi;
2257
2258 setup_timer(&plat_priv->fw_boot_timer,
2259 fw_boot_timeout, (unsigned long)plat_priv);
2260
2261 register_pm_notifier(&cnss_pm_notifier);
2262
2263 ret = device_init_wakeup(&plat_dev->dev, true);
2264 if (ret)
2265 cnss_pr_err("Failed to init platform device wakeup source, err = %d\n",
2266 ret);
2267
2268 init_completion(&plat_priv->power_up_complete);
2269 mutex_init(&plat_priv->dev_lock);
2270
2271 cnss_pr_info("Platform driver probed successfully.\n");
2272
2273 return 0;
2274
2275deinit_qmi:
2276 cnss_qmi_deinit(plat_priv);
2277deinit_event_work:
2278 cnss_event_work_deinit(plat_priv);
2279remove_sysfs:
2280 cnss_remove_sysfs(plat_priv);
2281unreg_bus_scale:
2282 cnss_unregister_bus_scale(plat_priv);
2283unreg_esoc:
2284 cnss_unregister_esoc(plat_priv);
2285deinit_pci:
2286 if (!test_bit(SKIP_DEVICE_BOOT, &quirks))
2287 cnss_pci_deinit(plat_priv);
2288power_off:
2289 if (!test_bit(SKIP_DEVICE_BOOT, &quirks))
2290 cnss_power_off_device(plat_priv);
2291free_res:
2292 cnss_put_resources(plat_priv);
2293reset_ctx:
2294 platform_set_drvdata(plat_dev, NULL);
2295 cnss_set_plat_priv(plat_dev, NULL);
2296out:
2297 return ret;
2298}
2299
2300static int cnss_remove(struct platform_device *plat_dev)
2301{
2302 struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev);
2303
2304 complete_all(&plat_priv->power_up_complete);
2305 device_init_wakeup(&plat_dev->dev, false);
2306 unregister_pm_notifier(&cnss_pm_notifier);
2307 del_timer(&plat_priv->fw_boot_timer);
2308 cnss_debugfs_destroy(plat_priv);
2309 cnss_qmi_deinit(plat_priv);
2310 cnss_event_work_deinit(plat_priv);
2311 cnss_remove_sysfs(plat_priv);
2312 cnss_unregister_bus_scale(plat_priv);
2313 cnss_unregister_esoc(plat_priv);
2314 cnss_pci_deinit(plat_priv);
2315 cnss_put_resources(plat_priv);
2316 platform_set_drvdata(plat_dev, NULL);
2317 plat_env = NULL;
2318
2319 return 0;
2320}
2321
2322static struct platform_driver cnss_platform_driver = {
2323 .probe = cnss_probe,
2324 .remove = cnss_remove,
2325 .driver = {
2326 .name = "cnss2",
2327 .owner = THIS_MODULE,
2328 .of_match_table = cnss_of_match_table,
2329#ifdef CONFIG_CNSS_ASYNC
2330 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
2331#endif
2332 },
2333};
2334
2335static int __init cnss_initialize(void)
2336{
2337 int ret = 0;
2338
2339 cnss_debug_init();
2340 ret = platform_driver_register(&cnss_platform_driver);
2341 if (ret)
2342 cnss_debug_deinit();
2343
2344 return ret;
2345}
2346
2347static void __exit cnss_exit(void)
2348{
2349 platform_driver_unregister(&cnss_platform_driver);
2350 cnss_debug_deinit();
2351}
2352
2353module_init(cnss_initialize);
2354module_exit(cnss_exit);
2355
2356MODULE_LICENSE("GPL v2");
2357MODULE_DESCRIPTION("CNSS2 Platform Driver");