xref: /wlan-driver/platform/icnss2/main.c (revision 5113495b16420b49004c444715d2daae2066e7dc) !
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015-2020, 2021, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #define pr_fmt(fmt) "icnss2: " fmt
8 
9 #include <linux/of_address.h>
10 #include <linux/clk.h>
11 #include <linux/iommu.h>
12 #include <linux/export.h>
13 #include <linux/err.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/init.h>
17 #include <linux/io.h>
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/debugfs.h>
21 #include <linux/seq_file.h>
22 #include <linux/slab.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/interrupt.h>
25 #include <linux/sched.h>
26 #include <linux/delay.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/thread_info.h>
29 #include <linux/uaccess.h>
30 #include <linux/etherdevice.h>
31 #include <linux/of.h>
32 #include <linux/of_irq.h>
33 #include <linux/pm_runtime.h>
34 #include <linux/soc/qcom/qmi.h>
35 #include <linux/sysfs.h>
36 #include <linux/thermal.h>
37 #include <soc/qcom/memory_dump.h>
38 #include <soc/qcom/secure_buffer.h>
39 #include <soc/qcom/socinfo.h>
40 #include <soc/qcom/qcom_ramdump.h>
41 #include <linux/soc/qcom/smem.h>
42 #include <linux/soc/qcom/smem_state.h>
43 #include <linux/remoteproc.h>
44 #include <linux/remoteproc/qcom_rproc.h>
45 #include <linux/soc/qcom/pdr.h>
46 #include <linux/remoteproc.h>
47 #include <linux/version.h>
48 #include <trace/hooks/remoteproc.h>
49 #ifdef CONFIG_SLATE_MODULE_ENABLED
50 #include <linux/soc/qcom/slatecom_interface.h>
51 #include <linux/soc/qcom/slate_events_bridge_intf.h>
52 #include <uapi/linux/slatecom_interface.h>
53 #endif
54 #include "main.h"
55 #include "qmi.h"
56 #include "debug.h"
57 #include "power.h"
58 #include "genl.h"
59 
60 #define MAX_PROP_SIZE			32
61 #define NUM_LOG_PAGES			10
62 #define NUM_LOG_LONG_PAGES		4
63 #define ICNSS_MAGIC			0x5abc5abc
64 
65 #define ICNSS_WLAN_SERVICE_NAME					"wlan/fw"
66 #define ICNSS_WLANPD_NAME					"msm/modem/wlan_pd"
67 #define ICNSS_DEFAULT_FEATURE_MASK 0x01
68 
69 #define ICNSS_M3_SEGMENT(segment)		"wcnss_"segment
70 #define ICNSS_M3_SEGMENT_PHYAREG		"phyareg"
71 #define ICNSS_M3_SEGMENT_PHYA			"phydbg"
72 #define ICNSS_M3_SEGMENT_WMACREG		"wmac0reg"
73 #define ICNSS_M3_SEGMENT_WCSSDBG		"WCSSDBG"
74 #define ICNSS_M3_SEGMENT_PHYAM3			"PHYAPDMEM"
75 
76 #define ICNSS_QUIRKS_DEFAULT		BIT(FW_REJUVENATE_ENABLE)
77 #define ICNSS_MAX_PROBE_CNT		2
78 
79 #define ICNSS_BDF_TYPE_DEFAULT         ICNSS_BDF_ELF
80 
81 #define PROBE_TIMEOUT                 15000
82 #define SMP2P_SOC_WAKE_TIMEOUT        500
83 #ifdef CONFIG_ICNSS2_DEBUG
84 static unsigned long qmi_timeout = 3000;
85 module_param(qmi_timeout, ulong, 0600);
86 #define WLFW_TIMEOUT                    msecs_to_jiffies(qmi_timeout)
87 #else
88 #define WLFW_TIMEOUT                    msecs_to_jiffies(3000)
89 #endif
90 
91 #define ICNSS_RECOVERY_TIMEOUT		60000
92 #define ICNSS_WPSS_SSR_TIMEOUT          5000
93 #define ICNSS_CAL_TIMEOUT		40000
94 
95 static struct icnss_priv *penv;
96 static struct work_struct wpss_loader;
97 static struct work_struct wpss_ssr_work;
98 uint64_t dynamic_feature_mask = ICNSS_DEFAULT_FEATURE_MASK;
99 
100 #define ICNSS_EVENT_PENDING			2989
101 
102 #define ICNSS_EVENT_SYNC			BIT(0)
103 #define ICNSS_EVENT_UNINTERRUPTIBLE		BIT(1)
104 #define ICNSS_EVENT_SYNC_UNINTERRUPTIBLE	(ICNSS_EVENT_UNINTERRUPTIBLE | \
105 						 ICNSS_EVENT_SYNC)
106 #define ICNSS_DMS_QMI_CONNECTION_WAIT_MS 50
107 #define ICNSS_DMS_QMI_CONNECTION_WAIT_RETRY 200
108 
109 #define SMP2P_GET_MAX_RETRY		4
110 #define SMP2P_GET_RETRY_DELAY_MS	500
111 
112 #define RAMDUMP_NUM_DEVICES		256
113 #define ICNSS_RAMDUMP_NAME		"icnss_ramdump"
114 
115 #define WLAN_EN_TEMP_THRESHOLD		5000
116 #define WLAN_EN_DELAY			500
117 
118 #define ICNSS_RPROC_LEN			100
119 static DEFINE_IDA(rd_minor_id);
120 
121 enum icnss_pdr_cause_index {
122 	ICNSS_FW_CRASH,
123 	ICNSS_ROOT_PD_CRASH,
124 	ICNSS_ROOT_PD_SHUTDOWN,
125 	ICNSS_HOST_ERROR,
126 };
127 
128 static const char * const icnss_pdr_cause[] = {
129 	[ICNSS_FW_CRASH] = "FW crash",
130 	[ICNSS_ROOT_PD_CRASH] = "Root PD crashed",
131 	[ICNSS_ROOT_PD_SHUTDOWN] = "Root PD shutdown",
132 	[ICNSS_HOST_ERROR] = "Host error",
133 };
134 
icnss_set_plat_priv(struct icnss_priv * priv)135 static void icnss_set_plat_priv(struct icnss_priv *priv)
136 {
137 	penv = priv;
138 }
139 
icnss_get_plat_priv(void)140 static struct icnss_priv *icnss_get_plat_priv(void)
141 {
142 	return penv;
143 }
144 
icnss_wpss_unload(struct icnss_priv * priv)145 static inline void icnss_wpss_unload(struct icnss_priv *priv)
146 {
147 	if (priv && priv->rproc) {
148 		rproc_shutdown(priv->rproc);
149 		rproc_put(priv->rproc);
150 		priv->rproc = NULL;
151 	}
152 }
153 
icnss_sysfs_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)154 static ssize_t icnss_sysfs_store(struct kobject *kobj,
155 				 struct kobj_attribute *attr,
156 				 const char *buf, size_t count)
157 {
158 	struct icnss_priv *priv = icnss_get_plat_priv();
159 
160 	if (!priv)
161 		return count;
162 
163 	icnss_pr_dbg("Received shutdown indication");
164 
165 	atomic_set(&priv->is_shutdown, true);
166 	if ((priv->wpss_supported || priv->rproc_fw_download) &&
167 	    priv->device_id == ADRASTEA_DEVICE_ID)
168 		icnss_wpss_unload(priv);
169 	return count;
170 }
171 
172 static struct kobj_attribute icnss_sysfs_attribute =
173 __ATTR(shutdown, 0660, NULL, icnss_sysfs_store);
174 
icnss_pm_stay_awake(struct icnss_priv * priv)175 static void icnss_pm_stay_awake(struct icnss_priv *priv)
176 {
177 	if (atomic_inc_return(&priv->pm_count) != 1)
178 		return;
179 
180 	icnss_pr_vdbg("PM stay awake, state: 0x%lx, count: %d\n", priv->state,
181 		     atomic_read(&priv->pm_count));
182 
183 	pm_stay_awake(&priv->pdev->dev);
184 
185 	priv->stats.pm_stay_awake++;
186 }
187 
icnss_pm_relax(struct icnss_priv * priv)188 static void icnss_pm_relax(struct icnss_priv *priv)
189 {
190 	int r = atomic_dec_return(&priv->pm_count);
191 
192 	WARN_ON(r < 0);
193 
194 	if (r != 0)
195 		return;
196 
197 	icnss_pr_vdbg("PM relax, state: 0x%lx, count: %d\n", priv->state,
198 		     atomic_read(&priv->pm_count));
199 
200 	pm_relax(&priv->pdev->dev);
201 	priv->stats.pm_relax++;
202 }
203 
icnss_driver_event_to_str(enum icnss_driver_event_type type)204 char *icnss_driver_event_to_str(enum icnss_driver_event_type type)
205 {
206 	switch (type) {
207 	case ICNSS_DRIVER_EVENT_SERVER_ARRIVE:
208 		return "SERVER_ARRIVE";
209 	case ICNSS_DRIVER_EVENT_SERVER_EXIT:
210 		return "SERVER_EXIT";
211 	case ICNSS_DRIVER_EVENT_FW_READY_IND:
212 		return "FW_READY";
213 	case ICNSS_DRIVER_EVENT_REGISTER_DRIVER:
214 		return "REGISTER_DRIVER";
215 	case ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
216 		return "UNREGISTER_DRIVER";
217 	case ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN:
218 		return "PD_SERVICE_DOWN";
219 	case ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND:
220 		return "FW_EARLY_CRASH_IND";
221 	case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
222 		return "IDLE_SHUTDOWN";
223 	case ICNSS_DRIVER_EVENT_IDLE_RESTART:
224 		return "IDLE_RESTART";
225 	case ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND:
226 		return "FW_INIT_DONE";
227 	case ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM:
228 		return "QDSS_TRACE_REQ_MEM";
229 	case ICNSS_DRIVER_EVENT_QDSS_TRACE_SAVE:
230 		return "QDSS_TRACE_SAVE";
231 	case ICNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
232 		return "QDSS_TRACE_FREE";
233 	case ICNSS_DRIVER_EVENT_M3_DUMP_UPLOAD_REQ:
234 		return "M3_DUMP_UPLOAD";
235 	case ICNSS_DRIVER_EVENT_IMS_WFC_CALL_IND:
236 		return "IMS_WFC_CALL_IND";
237 	case ICNSS_DRIVER_EVENT_WLFW_TWT_CFG_IND:
238 		return "WLFW_TWC_CFG_IND";
239 	case ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_DATA:
240 		return "QDSS_TRACE_REQ_DATA";
241 	case ICNSS_DRIVER_EVENT_SUBSYS_RESTART_LEVEL:
242 		return "SUBSYS_RESTART_LEVEL";
243 	case ICNSS_DRIVER_EVENT_MAX:
244 		return "EVENT_MAX";
245 	}
246 
247 	return "UNKNOWN";
248 };
249 
icnss_soc_wake_event_to_str(enum icnss_soc_wake_event_type type)250 char *icnss_soc_wake_event_to_str(enum icnss_soc_wake_event_type type)
251 {
252 	switch (type) {
253 	case ICNSS_SOC_WAKE_REQUEST_EVENT:
254 		return "SOC_WAKE_REQUEST";
255 	case ICNSS_SOC_WAKE_RELEASE_EVENT:
256 		return "SOC_WAKE_RELEASE";
257 	case ICNSS_SOC_WAKE_EVENT_MAX:
258 		return "SOC_EVENT_MAX";
259 	}
260 
261 	return "UNKNOWN";
262 };
263 
icnss_driver_event_post(struct icnss_priv * priv,enum icnss_driver_event_type type,u32 flags,void * data)264 int icnss_driver_event_post(struct icnss_priv *priv,
265 			    enum icnss_driver_event_type type,
266 			    u32 flags, void *data)
267 {
268 	struct icnss_driver_event *event;
269 	unsigned long irq_flags;
270 	int gfp = GFP_KERNEL;
271 	int ret = 0;
272 
273 	if (!priv)
274 		return -ENODEV;
275 
276 	icnss_pr_dbg("Posting event: %s(%d), %s, flags: 0x%x, state: 0x%lx\n",
277 		     icnss_driver_event_to_str(type), type, current->comm,
278 		     flags, priv->state);
279 
280 	if (type >= ICNSS_DRIVER_EVENT_MAX) {
281 		icnss_pr_err("Invalid Event type: %d, can't post", type);
282 		return -EINVAL;
283 	}
284 
285 	if (in_interrupt() || !preemptible() || rcu_preempt_depth())
286 		gfp = GFP_ATOMIC;
287 
288 	event = kzalloc(sizeof(*event), gfp);
289 	if (event == NULL)
290 		return -ENOMEM;
291 
292 	icnss_pm_stay_awake(priv);
293 
294 	event->type = type;
295 	event->data = data;
296 	init_completion(&event->complete);
297 	event->ret = ICNSS_EVENT_PENDING;
298 	event->sync = !!(flags & ICNSS_EVENT_SYNC);
299 
300 	spin_lock_irqsave(&priv->event_lock, irq_flags);
301 	list_add_tail(&event->list, &priv->event_list);
302 	spin_unlock_irqrestore(&priv->event_lock, irq_flags);
303 
304 	priv->stats.events[type].posted++;
305 	queue_work(priv->event_wq, &priv->event_work);
306 
307 	if (!(flags & ICNSS_EVENT_SYNC))
308 		goto out;
309 
310 	if (flags & ICNSS_EVENT_UNINTERRUPTIBLE)
311 		wait_for_completion(&event->complete);
312 	else
313 		ret = wait_for_completion_interruptible(&event->complete);
314 
315 	icnss_pr_dbg("Completed event: %s(%d), state: 0x%lx, ret: %d/%d\n",
316 		     icnss_driver_event_to_str(type), type, priv->state, ret,
317 		     event->ret);
318 
319 	spin_lock_irqsave(&priv->event_lock, irq_flags);
320 	if (ret == -ERESTARTSYS && event->ret == ICNSS_EVENT_PENDING) {
321 		event->sync = false;
322 		spin_unlock_irqrestore(&priv->event_lock, irq_flags);
323 		ret = -EINTR;
324 		goto out;
325 	}
326 	spin_unlock_irqrestore(&priv->event_lock, irq_flags);
327 
328 	ret = event->ret;
329 	kfree(event);
330 
331 out:
332 	icnss_pm_relax(priv);
333 	return ret;
334 }
335 
icnss_soc_wake_event_post(struct icnss_priv * priv,enum icnss_soc_wake_event_type type,u32 flags,void * data)336 int icnss_soc_wake_event_post(struct icnss_priv *priv,
337 			      enum icnss_soc_wake_event_type type,
338 			      u32 flags, void *data)
339 {
340 	struct icnss_soc_wake_event *event;
341 	unsigned long irq_flags;
342 	int gfp = GFP_KERNEL;
343 	int ret = 0;
344 
345 	if (!priv)
346 		return -ENODEV;
347 
348 	icnss_pr_soc_wake("Posting event: %s(%d), %s, flags: 0x%x, state: 0x%lx\n",
349 			  icnss_soc_wake_event_to_str(type),
350 			  type, current->comm, flags, priv->state);
351 
352 	if (type >= ICNSS_SOC_WAKE_EVENT_MAX) {
353 		icnss_pr_err("Invalid Event type: %d, can't post", type);
354 		return -EINVAL;
355 	}
356 
357 	if (in_interrupt() || irqs_disabled())
358 		gfp = GFP_ATOMIC;
359 
360 	event = kzalloc(sizeof(*event), gfp);
361 	if (!event)
362 		return -ENOMEM;
363 
364 	icnss_pm_stay_awake(priv);
365 
366 	event->type = type;
367 	event->data = data;
368 	init_completion(&event->complete);
369 	event->ret = ICNSS_EVENT_PENDING;
370 	event->sync = !!(flags & ICNSS_EVENT_SYNC);
371 
372 	spin_lock_irqsave(&priv->soc_wake_msg_lock, irq_flags);
373 	list_add_tail(&event->list, &priv->soc_wake_msg_list);
374 	spin_unlock_irqrestore(&priv->soc_wake_msg_lock, irq_flags);
375 
376 	priv->stats.soc_wake_events[type].posted++;
377 	queue_work(priv->soc_wake_wq, &priv->soc_wake_msg_work);
378 
379 	if (!(flags & ICNSS_EVENT_SYNC))
380 		goto out;
381 
382 	if (flags & ICNSS_EVENT_UNINTERRUPTIBLE)
383 		wait_for_completion(&event->complete);
384 	else
385 		ret = wait_for_completion_interruptible(&event->complete);
386 
387 	icnss_pr_soc_wake("Completed event: %s(%d), state: 0x%lx, ret: %d/%d\n",
388 			  icnss_soc_wake_event_to_str(type),
389 			  type, priv->state, ret, event->ret);
390 
391 	spin_lock_irqsave(&priv->soc_wake_msg_lock, irq_flags);
392 	if (ret == -ERESTARTSYS && event->ret == ICNSS_EVENT_PENDING) {
393 		event->sync = false;
394 		spin_unlock_irqrestore(&priv->soc_wake_msg_lock, irq_flags);
395 		ret = -EINTR;
396 		goto out;
397 	}
398 	spin_unlock_irqrestore(&priv->soc_wake_msg_lock, irq_flags);
399 
400 	ret = event->ret;
401 	kfree(event);
402 
403 out:
404 	icnss_pm_relax(priv);
405 	return ret;
406 }
407 
icnss_is_fw_ready(void)408 bool icnss_is_fw_ready(void)
409 {
410 	if (!penv)
411 		return false;
412 	else
413 		return test_bit(ICNSS_FW_READY, &penv->state);
414 }
415 EXPORT_SYMBOL(icnss_is_fw_ready);
416 
icnss_block_shutdown(bool status)417 void icnss_block_shutdown(bool status)
418 {
419 	if (!penv)
420 		return;
421 
422 	if (status) {
423 		set_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state);
424 		reinit_completion(&penv->unblock_shutdown);
425 	} else {
426 		clear_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state);
427 		complete(&penv->unblock_shutdown);
428 	}
429 }
430 EXPORT_SYMBOL(icnss_block_shutdown);
431 
icnss_is_fw_down(void)432 bool icnss_is_fw_down(void)
433 {
434 
435 	struct icnss_priv *priv = icnss_get_plat_priv();
436 
437 	if (!priv)
438 		return false;
439 
440 	return test_bit(ICNSS_FW_DOWN, &priv->state) ||
441 		test_bit(ICNSS_PD_RESTART, &priv->state) ||
442 		test_bit(ICNSS_REJUVENATE, &priv->state);
443 }
444 EXPORT_SYMBOL(icnss_is_fw_down);
445 
icnss_get_device_config(void)446 unsigned long icnss_get_device_config(void)
447 {
448 	struct icnss_priv *priv = icnss_get_plat_priv();
449 
450 	if (!priv)
451 		return 0;
452 
453 	return priv->device_config;
454 }
455 EXPORT_SYMBOL(icnss_get_device_config);
456 
icnss_is_rejuvenate(void)457 bool icnss_is_rejuvenate(void)
458 {
459 	if (!penv)
460 		return false;
461 	else
462 		return test_bit(ICNSS_REJUVENATE, &penv->state);
463 }
464 EXPORT_SYMBOL(icnss_is_rejuvenate);
465 
icnss_is_pdr(void)466 bool icnss_is_pdr(void)
467 {
468 	if (!penv)
469 		return false;
470 	else
471 		return test_bit(ICNSS_PDR, &penv->state);
472 }
473 EXPORT_SYMBOL(icnss_is_pdr);
474 
icnss_is_smp2p_valid(struct icnss_priv * priv,enum smp2p_out_entry smp2p_entry)475 static bool icnss_is_smp2p_valid(struct icnss_priv *priv,
476 			  enum smp2p_out_entry smp2p_entry)
477 {
478 	if (priv->device_id == WCN6750_DEVICE_ID ||
479 	    priv->device_id == WCN6450_DEVICE_ID ||
480 	    priv->wpss_supported)
481 		return IS_ERR_OR_NULL(priv->smp2p_info[smp2p_entry].smem_state);
482 	else
483 		return 0;
484 }
485 
icnss_send_smp2p(struct icnss_priv * priv,enum icnss_smp2p_msg_id msg_id,enum smp2p_out_entry smp2p_entry)486 static int icnss_send_smp2p(struct icnss_priv *priv,
487 			    enum icnss_smp2p_msg_id msg_id,
488 			    enum smp2p_out_entry smp2p_entry)
489 {
490 	unsigned int value = 0;
491 	int ret;
492 
493 	if (!priv || icnss_is_smp2p_valid(priv, smp2p_entry))
494 		return -EINVAL;
495 
496 	/* No Need to check FW_DOWN for ICNSS_RESET_MSG */
497 	if (msg_id == ICNSS_RESET_MSG) {
498 		priv->smp2p_info[smp2p_entry].seq = 0;
499 		ret = qcom_smem_state_update_bits(
500 				priv->smp2p_info[smp2p_entry].smem_state,
501 				ICNSS_SMEM_VALUE_MASK,
502 				0);
503 		if (ret)
504 			icnss_pr_err("Error in SMP2P sent. ret: %d, %s\n",
505 				     ret, icnss_smp2p_str[smp2p_entry]);
506 
507 		return ret;
508 	}
509 
510 	if (test_bit(ICNSS_FW_DOWN, &priv->state) ||
511 	    !test_bit(ICNSS_FW_READY, &priv->state)) {
512 		icnss_pr_smp2p("FW down, ignoring sending SMP2P state: 0x%lx\n",
513 				  priv->state);
514 		return -EINVAL;
515 	}
516 
517 	value |= priv->smp2p_info[smp2p_entry].seq++;
518 	value <<= ICNSS_SMEM_SEQ_NO_POS;
519 	value |= msg_id;
520 
521 	icnss_pr_smp2p("Sending SMP2P value: 0x%X\n", value);
522 
523 	if (msg_id == ICNSS_SOC_WAKE_REQ || msg_id == ICNSS_SOC_WAKE_REL)
524 		reinit_completion(&penv->smp2p_soc_wake_wait);
525 
526 	ret = qcom_smem_state_update_bits(
527 			priv->smp2p_info[smp2p_entry].smem_state,
528 			ICNSS_SMEM_VALUE_MASK,
529 			value);
530 	if (ret) {
531 		icnss_pr_smp2p("Error in SMP2P send ret: %d, %s\n", ret,
532 			       icnss_smp2p_str[smp2p_entry]);
533 	} else {
534 		if (msg_id == ICNSS_SOC_WAKE_REQ ||
535 		    msg_id == ICNSS_SOC_WAKE_REL) {
536 			if (!wait_for_completion_timeout(
537 					&priv->smp2p_soc_wake_wait,
538 					msecs_to_jiffies(SMP2P_SOC_WAKE_TIMEOUT))) {
539 				icnss_pr_err("SMP2P Soc Wake timeout msg %d, %s\n", msg_id,
540 					     icnss_smp2p_str[smp2p_entry]);
541 				if (!test_bit(ICNSS_FW_DOWN, &priv->state))
542 					ICNSS_ASSERT(0);
543 			}
544 		}
545 	}
546 
547 	return ret;
548 }
549 
icnss_is_low_power(void)550 bool icnss_is_low_power(void)
551 {
552 	if (!penv)
553 		return false;
554 	else
555 		return test_bit(ICNSS_LOW_POWER, &penv->state);
556 }
557 EXPORT_SYMBOL(icnss_is_low_power);
558 
fw_error_fatal_handler(int irq,void * ctx)559 static irqreturn_t fw_error_fatal_handler(int irq, void *ctx)
560 {
561 	struct icnss_priv *priv = ctx;
562 
563 	if (priv)
564 		priv->force_err_fatal = true;
565 
566 	icnss_pr_err("Received force error fatal request from FW\n");
567 
568 	return IRQ_HANDLED;
569 }
570 
fw_crash_indication_handler(int irq,void * ctx)571 static irqreturn_t fw_crash_indication_handler(int irq, void *ctx)
572 {
573 	struct icnss_priv *priv = ctx;
574 	struct icnss_uevent_fw_down_data fw_down_data = {0};
575 
576 	icnss_pr_err("Received early crash indication from FW\n");
577 
578 	if (priv) {
579 		if (priv->wpss_self_recovery_enabled)
580 			mod_timer(&priv->wpss_ssr_timer,
581 				  jiffies + msecs_to_jiffies(ICNSS_WPSS_SSR_TIMEOUT));
582 
583 		set_bit(ICNSS_FW_DOWN, &priv->state);
584 		icnss_ignore_fw_timeout(true);
585 
586 		if (test_bit(ICNSS_FW_READY, &priv->state)) {
587 			clear_bit(ICNSS_FW_READY, &priv->state);
588 			fw_down_data.crashed = true;
589 			icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN,
590 						 &fw_down_data);
591 		}
592 	}
593 
594 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND,
595 				0, NULL);
596 
597 	return IRQ_HANDLED;
598 }
599 
register_fw_error_notifications(struct device * dev)600 static void register_fw_error_notifications(struct device *dev)
601 {
602 	struct icnss_priv *priv = dev_get_drvdata(dev);
603 	struct device_node *dev_node;
604 	int irq = 0, ret = 0;
605 
606 	if (!priv)
607 		return;
608 
609 	dev_node = of_find_node_by_name(NULL, "qcom,smp2p_map_wlan_1_in");
610 	if (!dev_node) {
611 		icnss_pr_err("Failed to get smp2p node for force-fatal-error\n");
612 		return;
613 	}
614 
615 	icnss_pr_dbg("smp2p node->name=%s\n", dev_node->name);
616 
617 	if (strcmp("qcom,smp2p_map_wlan_1_in", dev_node->name) == 0) {
618 		ret = irq = of_irq_get_byname(dev_node,
619 					      "qcom,smp2p-force-fatal-error");
620 		if (ret < 0) {
621 			icnss_pr_err("Unable to get force-fatal-error irq %d\n",
622 				     irq);
623 			return;
624 		}
625 	}
626 
627 	ret = devm_request_threaded_irq(dev, irq, NULL, fw_error_fatal_handler,
628 					IRQF_ONESHOT | IRQF_TRIGGER_RISING,
629 					"wlanfw-err", priv);
630 	if (ret < 0) {
631 		icnss_pr_err("Unable to register for error fatal IRQ handler %d ret = %d",
632 			     irq, ret);
633 		return;
634 	}
635 	icnss_pr_dbg("FW force error fatal handler registered irq = %d\n", irq);
636 	priv->fw_error_fatal_irq = irq;
637 }
638 
register_early_crash_notifications(struct device * dev)639 static void register_early_crash_notifications(struct device *dev)
640 {
641 	struct icnss_priv *priv = dev_get_drvdata(dev);
642 	struct device_node *dev_node;
643 	int irq = 0, ret = 0;
644 
645 	if (!priv)
646 		return;
647 
648 	dev_node = of_find_node_by_name(NULL, "qcom,smp2p_map_wlan_1_in");
649 	if (!dev_node) {
650 		icnss_pr_err("Failed to get smp2p node for early-crash-ind\n");
651 		return;
652 	}
653 
654 	icnss_pr_dbg("smp2p node->name=%s\n", dev_node->name);
655 
656 	if (strcmp("qcom,smp2p_map_wlan_1_in", dev_node->name) == 0) {
657 		ret = irq = of_irq_get_byname(dev_node,
658 					      "qcom,smp2p-early-crash-ind");
659 		if (ret < 0) {
660 			icnss_pr_err("Unable to get early-crash-ind irq %d\n",
661 				     irq);
662 			return;
663 		}
664 	}
665 
666 	ret = devm_request_threaded_irq(dev, irq, NULL,
667 					fw_crash_indication_handler,
668 					IRQF_ONESHOT | IRQF_TRIGGER_RISING,
669 					"wlanfw-early-crash-ind", priv);
670 	if (ret < 0) {
671 		icnss_pr_err("Unable to register for early crash indication IRQ handler %d ret = %d",
672 			     irq, ret);
673 		return;
674 	}
675 	icnss_pr_dbg("FW crash indication handler registered irq = %d\n", irq);
676 	priv->fw_early_crash_irq = irq;
677 }
678 
icnss_get_temperature(struct icnss_priv * priv,int * temp)679 static int icnss_get_temperature(struct icnss_priv *priv, int *temp)
680 {
681 	struct thermal_zone_device *thermal_dev;
682 	const char *tsens;
683 	int ret;
684 
685 	ret = of_property_read_string(priv->pdev->dev.of_node,
686 				      "tsens",
687 				      &tsens);
688 	if (ret)
689 		return ret;
690 
691 	icnss_pr_dbg("Thermal Sensor is %s\n", tsens);
692 	thermal_dev = thermal_zone_get_zone_by_name(tsens);
693 	if (IS_ERR_OR_NULL(thermal_dev)) {
694 		icnss_pr_err("Fail to get thermal zone. ret: %d",
695 			     PTR_ERR(thermal_dev));
696 		return PTR_ERR(thermal_dev);
697 	}
698 
699 	ret = thermal_zone_get_temp(thermal_dev, temp);
700 	if (ret)
701 		icnss_pr_err("Fail to get temperature. ret: %d", ret);
702 
703 	return ret;
704 }
705 
fw_soc_wake_ack_handler(int irq,void * ctx)706 static irqreturn_t fw_soc_wake_ack_handler(int irq, void *ctx)
707 {
708 	struct icnss_priv *priv = ctx;
709 
710 	if (priv)
711 		complete(&priv->smp2p_soc_wake_wait);
712 
713 	return IRQ_HANDLED;
714 }
715 
register_soc_wake_notif(struct device * dev)716 static void register_soc_wake_notif(struct device *dev)
717 {
718 	struct icnss_priv *priv = dev_get_drvdata(dev);
719 	struct device_node *dev_node;
720 	int irq = 0, ret = 0;
721 
722 	if (!priv)
723 		return;
724 
725 	dev_node = of_find_node_by_name(NULL, "qcom,smp2p_map_wlan_2_in");
726 	if (!dev_node) {
727 		icnss_pr_err("Failed to get smp2p node for soc-wake-ack\n");
728 		return;
729 	}
730 
731 	icnss_pr_dbg("smp2p node->name=%s\n", dev_node->name);
732 
733 	if (strcmp("qcom,smp2p_map_wlan_2_in", dev_node->name) == 0) {
734 		ret = irq = of_irq_get_byname(dev_node,
735 					      "qcom,smp2p-soc-wake-ack");
736 		if (ret < 0) {
737 			icnss_pr_err("Unable to get soc wake ack irq %d\n",
738 				     irq);
739 			return;
740 		}
741 	}
742 
743 	ret = devm_request_threaded_irq(dev, irq, NULL,
744 					fw_soc_wake_ack_handler,
745 					IRQF_ONESHOT | IRQF_TRIGGER_RISING |
746 					IRQF_TRIGGER_FALLING,
747 					"wlanfw-soc-wake-ack", priv);
748 	if (ret < 0) {
749 		icnss_pr_err("Unable to register for SOC Wake ACK IRQ handler %d ret = %d",
750 			     irq, ret);
751 		return;
752 	}
753 	icnss_pr_dbg("FW SOC Wake ACK handler registered irq = %d\n", irq);
754 	priv->fw_soc_wake_ack_irq = irq;
755 }
756 
757 
icnss_call_driver_uevent(struct icnss_priv * priv,enum icnss_uevent uevent,void * data)758 int icnss_call_driver_uevent(struct icnss_priv *priv,
759 				    enum icnss_uevent uevent, void *data)
760 {
761 	struct icnss_uevent_data uevent_data;
762 
763 	if (!priv->ops || !priv->ops->uevent)
764 		return 0;
765 
766 	icnss_pr_dbg("Calling driver uevent state: 0x%lx, uevent: %d\n",
767 		     priv->state, uevent);
768 
769 	uevent_data.uevent = uevent;
770 	uevent_data.data = data;
771 
772 	return priv->ops->uevent(&priv->pdev->dev, &uevent_data);
773 }
774 
icnss_setup_dms_mac(struct icnss_priv * priv)775 static int icnss_setup_dms_mac(struct icnss_priv *priv)
776 {
777 	int i;
778 	int ret = 0;
779 
780 	ret = icnss_qmi_get_dms_mac(priv);
781 	if (ret == 0 && priv->dms.mac_valid)
782 		goto qmi_send;
783 
784 	/* DTSI property use-nv-mac is used to force DMS MAC address for WLAN.
785 	 * Thus assert on failure to get MAC from DMS even after retries
786 	 */
787 	if (priv->use_nv_mac) {
788 		for (i = 0; i < ICNSS_DMS_QMI_CONNECTION_WAIT_RETRY; i++) {
789 			if (priv->dms.mac_valid)
790 				break;
791 
792 			ret = icnss_qmi_get_dms_mac(priv);
793 			if (ret != -EAGAIN)
794 				break;
795 			msleep(ICNSS_DMS_QMI_CONNECTION_WAIT_MS);
796 		}
797 		if (!priv->dms.nv_mac_not_prov && !priv->dms.mac_valid) {
798 			icnss_pr_err("Unable to get MAC from DMS after retries\n");
799 			ICNSS_ASSERT(0);
800 			return -EINVAL;
801 		}
802 	}
803 qmi_send:
804 	if (priv->dms.mac_valid)
805 		ret =
806 		icnss_wlfw_wlan_mac_req_send_sync(priv, priv->dms.mac,
807 						  ARRAY_SIZE(priv->dms.mac));
808 	return ret;
809 }
810 
icnss_get_smp2p_info(struct icnss_priv * priv,enum smp2p_out_entry smp2p_entry)811 static void icnss_get_smp2p_info(struct icnss_priv *priv,
812 				 enum smp2p_out_entry smp2p_entry)
813 {
814 	int retry = 0;
815 	int error;
816 
817 	if (priv->smp2p_info[smp2p_entry].smem_state)
818 		return;
819 retry:
820 	priv->smp2p_info[smp2p_entry].smem_state =
821 		qcom_smem_state_get(&priv->pdev->dev,
822 				    icnss_smp2p_str[smp2p_entry],
823 				    &priv->smp2p_info[smp2p_entry].smem_bit);
824 	if (icnss_is_smp2p_valid(priv, smp2p_entry)) {
825 		if (retry++ < SMP2P_GET_MAX_RETRY) {
826 			error = PTR_ERR(priv->smp2p_info[smp2p_entry].smem_state);
827 			icnss_pr_err("Failed to get smem state, ret: %d Entry: %s",
828 				     error, icnss_smp2p_str[smp2p_entry]);
829 			msleep(SMP2P_GET_RETRY_DELAY_MS);
830 			goto retry;
831 		}
832 		ICNSS_ASSERT(0);
833 		return;
834 	}
835 
836 	icnss_pr_dbg("smem state, Entry: %s", icnss_smp2p_str[smp2p_entry]);
837 }
838 
839 static inline
icnss_set_wlan_en_delay(struct icnss_priv * priv)840 void icnss_set_wlan_en_delay(struct icnss_priv *priv)
841 {
842 	if (priv->wlan_en_delay_ms_user > WLAN_EN_DELAY) {
843 		priv->wlan_en_delay_ms = priv->wlan_en_delay_ms_user;
844 	} else {
845 		priv->wlan_en_delay_ms = WLAN_EN_DELAY;
846 	}
847 }
848 
icnss_rf_subtype_value_to_type(u32 val)849 static enum wlfw_wlan_rf_subtype_v01 icnss_rf_subtype_value_to_type(u32 val)
850 {
851 	switch (val) {
852 	case WLAN_RF_SLATE:
853 		return WLFW_WLAN_RF_SLATE_V01;
854 	case WLAN_RF_APACHE:
855 		return WLFW_WLAN_RF_APACHE_V01;
856 	default:
857 		return WLFW_WLAN_RF_SUBTYPE_MAX_VAL_V01;
858 	}
859 }
860 
861 #ifdef CONFIG_SLATE_MODULE_ENABLED
icnss_send_wlan_boot_init(void)862 static void icnss_send_wlan_boot_init(void)
863 {
864 	send_wlan_state(GMI_MGR_WLAN_BOOT_INIT);
865 	icnss_pr_info("sent wlan boot init command\n");
866 }
867 
icnss_send_wlan_boot_complete(void)868 static void icnss_send_wlan_boot_complete(void)
869 {
870 	send_wlan_state(GMI_MGR_WLAN_BOOT_COMPLETE);
871 	icnss_pr_info("sent wlan boot complete command\n");
872 }
873 
icnss_wait_for_slate_complete(struct icnss_priv * priv)874 static int icnss_wait_for_slate_complete(struct icnss_priv *priv)
875 {
876 	if (!test_bit(ICNSS_SLATE_UP, &priv->state)) {
877 		reinit_completion(&priv->slate_boot_complete);
878 		icnss_pr_err("Waiting for slate boot up notification, 0x%lx\n",
879 			     priv->state);
880 		wait_for_completion(&priv->slate_boot_complete);
881 	}
882 
883 	if (!test_bit(ICNSS_SLATE_UP, &priv->state))
884 		return -EINVAL;
885 
886 	icnss_send_wlan_boot_init();
887 
888 	return 0;
889 }
890 #else
icnss_send_wlan_boot_complete(void)891 static void icnss_send_wlan_boot_complete(void)
892 {
893 }
894 
icnss_wait_for_slate_complete(struct icnss_priv * priv)895 static int icnss_wait_for_slate_complete(struct icnss_priv *priv)
896 {
897 	return 0;
898 }
899 #endif
900 
icnss_driver_event_server_arrive(struct icnss_priv * priv,void * data)901 static int icnss_driver_event_server_arrive(struct icnss_priv *priv,
902 						 void *data)
903 {
904 	int ret = 0;
905 	int temp = 0;
906 	bool ignore_assert = false;
907 	enum wlfw_wlan_rf_subtype_v01 rf_subtype;
908 
909 	if (!priv)
910 		return -ENODEV;
911 
912 	set_bit(ICNSS_WLFW_EXISTS, &priv->state);
913 	clear_bit(ICNSS_FW_DOWN, &priv->state);
914 	clear_bit(ICNSS_FW_READY, &priv->state);
915 
916 	if (priv->is_slate_rfa) {
917 		ret = icnss_wait_for_slate_complete(priv);
918 		if (ret == -EINVAL) {
919 			icnss_pr_err("Slate complete failed\n");
920 			return ret;
921 		}
922 	}
923 
924 	icnss_ignore_fw_timeout(false);
925 
926 	if (test_bit(ICNSS_WLFW_CONNECTED, &priv->state)) {
927 		icnss_pr_err("QMI Server already in Connected State\n");
928 		ICNSS_ASSERT(0);
929 	}
930 
931 	ret = icnss_connect_to_fw_server(priv, data);
932 	if (ret)
933 		goto fail;
934 
935 	set_bit(ICNSS_WLFW_CONNECTED, &priv->state);
936 
937 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
938 		ret = icnss_hw_power_on(priv);
939 		if (ret)
940 			goto fail;
941 	}
942 
943 	ret = wlfw_ind_register_send_sync_msg(priv);
944 	if (ret < 0) {
945 		if (ret == -EALREADY) {
946 			ret = 0;
947 			goto qmi_registered;
948 		}
949 		ignore_assert = true;
950 		goto fail;
951 	}
952 
953 	if (priv->is_rf_subtype_valid) {
954 		rf_subtype = icnss_rf_subtype_value_to_type(priv->rf_subtype);
955 		if (rf_subtype != WLFW_WLAN_RF_SUBTYPE_MAX_VAL_V01) {
956 			ret = wlfw_wlan_hw_init_cfg_msg(priv, rf_subtype);
957 			if (ret < 0)
958 				icnss_pr_dbg("Sending rf_subtype failed ret %d\n",
959 					     ret);
960 		} else {
961 			icnss_pr_dbg("Invalid rf subtype %d in DT\n",
962 				     priv->rf_subtype);
963 		}
964 	}
965 
966 	if (priv->device_id == WCN6750_DEVICE_ID ||
967 	    priv->device_id == WCN6450_DEVICE_ID) {
968 		if (!icnss_get_temperature(priv, &temp)) {
969 			icnss_pr_dbg("Temperature: %d\n", temp);
970 			if (temp < WLAN_EN_TEMP_THRESHOLD)
971 				icnss_set_wlan_en_delay(priv);
972 		}
973 
974 		ret = wlfw_host_cap_send_sync(priv);
975 		if (ret < 0)
976 			goto fail;
977 	}
978 
979 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
980 		if (!priv->msa_va) {
981 			icnss_pr_err("Invalid MSA address\n");
982 			ret = -EINVAL;
983 			goto fail;
984 		}
985 
986 		ret = wlfw_msa_mem_info_send_sync_msg(priv);
987 		if (ret < 0) {
988 			ignore_assert = true;
989 			goto fail;
990 		}
991 
992 		ret = wlfw_msa_ready_send_sync_msg(priv);
993 		if (ret < 0) {
994 			ignore_assert = true;
995 			goto fail;
996 		}
997 	}
998 
999 	if (priv->device_id == WCN6450_DEVICE_ID)
1000 		icnss_hw_power_off(priv);
1001 
1002 	ret = wlfw_cap_send_sync_msg(priv);
1003 	if (ret < 0) {
1004 		ignore_assert = true;
1005 		goto fail;
1006 	}
1007 
1008 	if (priv->device_id == ADRASTEA_DEVICE_ID && priv->is_chain1_supported) {
1009 		ret = icnss_power_on_chain1_reg(priv);
1010 		if (ret) {
1011 			ignore_assert = true;
1012 			goto fail;
1013 		}
1014 	}
1015 
1016 	if (priv->device_id == WCN6750_DEVICE_ID ||
1017 	    priv->device_id == WCN6450_DEVICE_ID) {
1018 		ret = icnss_hw_power_on(priv);
1019 		if (ret)
1020 			goto fail;
1021 
1022 		ret = wlfw_device_info_send_msg(priv);
1023 		if (ret < 0) {
1024 			ignore_assert = true;
1025 			goto  device_info_failure;
1026 		}
1027 
1028 		priv->mem_base_va = devm_ioremap(&priv->pdev->dev,
1029 						 priv->mem_base_pa,
1030 						 priv->mem_base_size);
1031 		if (!priv->mem_base_va) {
1032 			icnss_pr_err("Ioremap failed for bar address\n");
1033 			goto device_info_failure;
1034 		}
1035 
1036 		icnss_pr_dbg("Non-Secured Bar Address pa: %pa, va: 0x%pK\n",
1037 			     &priv->mem_base_pa,
1038 			     priv->mem_base_va);
1039 
1040 		if (priv->mhi_state_info_pa)
1041 			priv->mhi_state_info_va = devm_ioremap(&priv->pdev->dev,
1042 						priv->mhi_state_info_pa,
1043 						PAGE_SIZE);
1044 		if (!priv->mhi_state_info_va)
1045 			icnss_pr_err("Ioremap failed for MHI info address\n");
1046 
1047 		icnss_pr_dbg("MHI state info Address pa: %pa, va: 0x%pK\n",
1048 			     &priv->mhi_state_info_pa,
1049 			     priv->mhi_state_info_va);
1050 	}
1051 
1052 	if (priv->bdf_download_support) {
1053 		icnss_wlfw_bdf_dnld_send_sync(priv, ICNSS_BDF_REGDB);
1054 
1055 		ret = icnss_wlfw_bdf_dnld_send_sync(priv,
1056 						    priv->ctrl_params.bdf_type);
1057 		if (ret < 0)
1058 			goto device_info_failure;
1059 	}
1060 
1061 	if (priv->device_id == WCN6450_DEVICE_ID) {
1062 		ret = icnss_wlfw_qdss_dnld_send_sync(priv);
1063 		if (ret < 0)
1064 			icnss_pr_info("Failed to download qdss config file for WCN6450, ret = %d\n",
1065 				      ret);
1066 	}
1067 
1068 	if (priv->device_id == WCN6750_DEVICE_ID ||
1069 	    priv->device_id == WCN6450_DEVICE_ID) {
1070 		if (!priv->fw_soc_wake_ack_irq)
1071 			register_soc_wake_notif(&priv->pdev->dev);
1072 
1073 		icnss_get_smp2p_info(priv, ICNSS_SMP2P_OUT_SOC_WAKE);
1074 		icnss_get_smp2p_info(priv, ICNSS_SMP2P_OUT_EP_POWER_SAVE);
1075 	}
1076 
1077 	if (priv->wpss_supported)
1078 		icnss_get_smp2p_info(priv, ICNSS_SMP2P_OUT_POWER_SAVE);
1079 
1080 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
1081 		if (priv->bdf_download_support) {
1082 			ret = wlfw_cal_report_req(priv);
1083 			if (ret < 0)
1084 				goto device_info_failure;
1085 		}
1086 
1087 		wlfw_dynamic_feature_mask_send_sync_msg(priv,
1088 							dynamic_feature_mask);
1089 	}
1090 
1091 	if (!priv->fw_error_fatal_irq)
1092 		register_fw_error_notifications(&priv->pdev->dev);
1093 
1094 	if (!priv->fw_early_crash_irq)
1095 		register_early_crash_notifications(&priv->pdev->dev);
1096 
1097 	if (priv->psf_supported)
1098 		queue_work(priv->soc_update_wq, &priv->soc_update_work);
1099 
1100 	return ret;
1101 
1102 device_info_failure:
1103 	icnss_hw_power_off(priv);
1104 fail:
1105 	ICNSS_ASSERT(ignore_assert);
1106 qmi_registered:
1107 	return ret;
1108 }
1109 
icnss_driver_event_server_exit(struct icnss_priv * priv)1110 static int icnss_driver_event_server_exit(struct icnss_priv *priv)
1111 {
1112 	if (!priv)
1113 		return -ENODEV;
1114 
1115 	icnss_pr_info("WLAN FW Service Disconnected: 0x%lx\n", priv->state);
1116 
1117 	icnss_clear_server(priv);
1118 
1119 	if (priv->psf_supported)
1120 		priv->last_updated_voltage = 0;
1121 
1122 	return 0;
1123 }
1124 
icnss_call_driver_probe(struct icnss_priv * priv)1125 static int icnss_call_driver_probe(struct icnss_priv *priv)
1126 {
1127 	int ret = 0;
1128 	int probe_cnt = 0;
1129 
1130 	if (!priv->ops || !priv->ops->probe)
1131 		return 0;
1132 
1133 	if (test_bit(ICNSS_DRIVER_PROBED, &priv->state))
1134 		return -EINVAL;
1135 
1136 	icnss_pr_dbg("Calling driver probe state: 0x%lx\n", priv->state);
1137 
1138 	icnss_hw_power_on(priv);
1139 
1140 	icnss_block_shutdown(true);
1141 	while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
1142 		ret = priv->ops->probe(&priv->pdev->dev);
1143 		probe_cnt++;
1144 		if (ret != -EPROBE_DEFER)
1145 			break;
1146 	}
1147 	if (ret < 0) {
1148 		icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n",
1149 			     ret, priv->state, probe_cnt);
1150 		icnss_block_shutdown(false);
1151 		goto out;
1152 	}
1153 
1154 	icnss_block_shutdown(false);
1155 	set_bit(ICNSS_DRIVER_PROBED, &priv->state);
1156 
1157 	return 0;
1158 
1159 out:
1160 	icnss_hw_power_off(priv);
1161 	return ret;
1162 }
1163 
icnss_call_driver_shutdown(struct icnss_priv * priv)1164 static int icnss_call_driver_shutdown(struct icnss_priv *priv)
1165 {
1166 	if (!test_bit(ICNSS_DRIVER_PROBED, &priv->state))
1167 		goto out;
1168 
1169 	if (!priv->ops || !priv->ops->shutdown)
1170 		goto out;
1171 
1172 	if (test_bit(ICNSS_SHUTDOWN_DONE, &priv->state))
1173 		goto out;
1174 
1175 	icnss_pr_dbg("Calling driver shutdown state: 0x%lx\n", priv->state);
1176 
1177 	priv->ops->shutdown(&priv->pdev->dev);
1178 	set_bit(ICNSS_SHUTDOWN_DONE, &priv->state);
1179 
1180 out:
1181 	return 0;
1182 }
1183 
icnss_pd_restart_complete(struct icnss_priv * priv)1184 static int icnss_pd_restart_complete(struct icnss_priv *priv)
1185 {
1186 	int ret = 0;
1187 
1188 	icnss_pm_relax(priv);
1189 
1190 	icnss_call_driver_shutdown(priv);
1191 
1192 	clear_bit(ICNSS_PDR, &priv->state);
1193 	clear_bit(ICNSS_REJUVENATE, &priv->state);
1194 	clear_bit(ICNSS_PD_RESTART, &priv->state);
1195 	clear_bit(ICNSS_LOW_POWER, &priv->state);
1196 	priv->early_crash_ind = false;
1197 	priv->is_ssr = false;
1198 
1199 	if (!priv->ops || !priv->ops->reinit)
1200 		goto out;
1201 
1202 	if (test_bit(ICNSS_FW_DOWN, &priv->state)) {
1203 		icnss_pr_err("FW is in bad state, state: 0x%lx\n",
1204 			     priv->state);
1205 		goto out;
1206 	}
1207 
1208 	if (!test_bit(ICNSS_DRIVER_PROBED, &priv->state))
1209 		goto call_probe;
1210 
1211 	icnss_pr_dbg("Calling driver reinit state: 0x%lx\n", priv->state);
1212 
1213 	icnss_hw_power_on(priv);
1214 
1215 	icnss_block_shutdown(true);
1216 
1217 	ret = priv->ops->reinit(&priv->pdev->dev);
1218 	if (ret < 0) {
1219 		icnss_fatal_err("Driver reinit failed: %d, state: 0x%lx\n",
1220 				ret, priv->state);
1221 		if (!priv->allow_recursive_recovery)
1222 			ICNSS_ASSERT(false);
1223 		icnss_block_shutdown(false);
1224 		goto out_power_off;
1225 	}
1226 
1227 	icnss_block_shutdown(false);
1228 	clear_bit(ICNSS_SHUTDOWN_DONE, &priv->state);
1229 	return 0;
1230 
1231 call_probe:
1232 	return icnss_call_driver_probe(priv);
1233 
1234 out_power_off:
1235 	icnss_hw_power_off(priv);
1236 
1237 out:
1238 	return ret;
1239 }
1240 
1241 
icnss_driver_event_fw_ready_ind(struct icnss_priv * priv,void * data)1242 static int icnss_driver_event_fw_ready_ind(struct icnss_priv *priv, void *data)
1243 {
1244 	int ret = 0;
1245 
1246 	if (!priv)
1247 		return -ENODEV;
1248 
1249 	del_timer(&priv->recovery_timer);
1250 	set_bit(ICNSS_FW_READY, &priv->state);
1251 	clear_bit(ICNSS_MODE_ON, &priv->state);
1252 	atomic_set(&priv->soc_wake_ref_count, 0);
1253 
1254 	if (priv->device_id == WCN6750_DEVICE_ID ||
1255 	    priv->device_id == WCN6450_DEVICE_ID)
1256 		icnss_free_qdss_mem(priv);
1257 
1258 	icnss_pr_info("WLAN FW is ready: 0x%lx\n", priv->state);
1259 
1260 	icnss_hw_power_off(priv);
1261 
1262 	if (!priv->pdev) {
1263 		icnss_pr_err("Device is not ready\n");
1264 		ret = -ENODEV;
1265 		goto out;
1266 	}
1267 
1268 	if (priv->is_slate_rfa && test_bit(ICNSS_SLATE_UP, &priv->state))
1269 		icnss_send_wlan_boot_complete();
1270 
1271 	if (test_bit(ICNSS_PD_RESTART, &priv->state)) {
1272 		ret = icnss_pd_restart_complete(priv);
1273 	} else {
1274 		if (priv->wpss_supported)
1275 			icnss_setup_dms_mac(priv);
1276 		ret = icnss_call_driver_probe(priv);
1277 	}
1278 
1279 	icnss_vreg_unvote(priv);
1280 
1281 out:
1282 	return ret;
1283 }
1284 
icnss_driver_event_fw_init_done(struct icnss_priv * priv,void * data)1285 static int icnss_driver_event_fw_init_done(struct icnss_priv *priv, void *data)
1286 {
1287 	int ret = 0;
1288 
1289 	if (!priv)
1290 		return -ENODEV;
1291 
1292 	icnss_pr_info("WLAN FW Initialization done: 0x%lx\n", priv->state);
1293 
1294 	if (priv->device_id == WCN6750_DEVICE_ID) {
1295 		ret = icnss_wlfw_qdss_dnld_send_sync(priv);
1296 		if (ret < 0)
1297 			icnss_pr_info("Failed to download qdss config file for WCN6750, ret = %d\n",
1298 				      ret);
1299 	}
1300 
1301 	if (test_bit(ICNSS_COLD_BOOT_CAL, &priv->state)) {
1302 		mod_timer(&priv->recovery_timer,
1303 			  jiffies + msecs_to_jiffies(ICNSS_CAL_TIMEOUT));
1304 		ret = wlfw_wlan_mode_send_sync_msg(priv,
1305 			(enum wlfw_driver_mode_enum_v01)ICNSS_CALIBRATION);
1306 	} else {
1307 		icnss_driver_event_fw_ready_ind(priv, NULL);
1308 	}
1309 
1310 	return ret;
1311 }
1312 
icnss_alloc_qdss_mem(struct icnss_priv * priv)1313 int icnss_alloc_qdss_mem(struct icnss_priv *priv)
1314 {
1315 	struct platform_device *pdev = priv->pdev;
1316 	struct icnss_fw_mem *qdss_mem = priv->qdss_mem;
1317 	int i, j;
1318 
1319 	for (i = 0; i < priv->qdss_mem_seg_len; i++) {
1320 		if (!qdss_mem[i].va && qdss_mem[i].size) {
1321 			qdss_mem[i].va =
1322 				dma_alloc_coherent(&pdev->dev,
1323 						   qdss_mem[i].size,
1324 						   &qdss_mem[i].pa,
1325 						   GFP_KERNEL);
1326 			if (!qdss_mem[i].va) {
1327 				icnss_pr_err("Failed to allocate QDSS memory for FW, size: 0x%zx, type: %u, chuck-ID: %d\n",
1328 					     qdss_mem[i].size,
1329 					     qdss_mem[i].type, i);
1330 				break;
1331 			}
1332 		}
1333 	}
1334 
1335 	/* Best-effort allocation for QDSS trace */
1336 	if (i < priv->qdss_mem_seg_len) {
1337 		for (j = i; j < priv->qdss_mem_seg_len; j++) {
1338 			qdss_mem[j].type = 0;
1339 			qdss_mem[j].size = 0;
1340 		}
1341 		priv->qdss_mem_seg_len = i;
1342 	}
1343 
1344 	return 0;
1345 }
1346 
icnss_free_qdss_mem(struct icnss_priv * priv)1347 void icnss_free_qdss_mem(struct icnss_priv *priv)
1348 {
1349 	struct platform_device *pdev = priv->pdev;
1350 	struct icnss_fw_mem *qdss_mem = priv->qdss_mem;
1351 	int i;
1352 
1353 	for (i = 0; i < priv->qdss_mem_seg_len; i++) {
1354 		if (qdss_mem[i].va && qdss_mem[i].size) {
1355 			icnss_pr_dbg("Freeing memory for QDSS: pa: %pa, size: 0x%zx, type: %u\n",
1356 				     &qdss_mem[i].pa, qdss_mem[i].size,
1357 				     qdss_mem[i].type);
1358 			dma_free_coherent(&pdev->dev,
1359 					  qdss_mem[i].size, qdss_mem[i].va,
1360 					  qdss_mem[i].pa);
1361 			qdss_mem[i].va = NULL;
1362 			qdss_mem[i].pa = 0;
1363 			qdss_mem[i].size = 0;
1364 			qdss_mem[i].type = 0;
1365 		}
1366 	}
1367 	priv->qdss_mem_seg_len = 0;
1368 }
1369 
icnss_qdss_trace_req_mem_hdlr(struct icnss_priv * priv)1370 static int icnss_qdss_trace_req_mem_hdlr(struct icnss_priv *priv)
1371 {
1372 	int ret = 0;
1373 
1374 	ret = icnss_alloc_qdss_mem(priv);
1375 	if (ret < 0)
1376 		return ret;
1377 
1378 	return wlfw_qdss_trace_mem_info_send_sync(priv);
1379 }
1380 
icnss_qdss_trace_pa_to_va(struct icnss_priv * priv,u64 pa,u32 size,int * seg_id)1381 static void *icnss_qdss_trace_pa_to_va(struct icnss_priv *priv,
1382 				       u64 pa, u32 size, int *seg_id)
1383 {
1384 	int i = 0;
1385 	struct icnss_fw_mem *qdss_mem = priv->qdss_mem;
1386 	u64 offset = 0;
1387 	void *va = NULL;
1388 	u64 local_pa;
1389 	u32 local_size;
1390 
1391 	for (i = 0; i < priv->qdss_mem_seg_len; i++) {
1392 		local_pa = (u64)qdss_mem[i].pa;
1393 		local_size = (u32)qdss_mem[i].size;
1394 		if (pa == local_pa && size <= local_size) {
1395 			va = qdss_mem[i].va;
1396 			break;
1397 		}
1398 		if (pa > local_pa &&
1399 		    pa < local_pa + local_size &&
1400 		    pa + size <= local_pa + local_size) {
1401 			offset = pa - local_pa;
1402 			va = qdss_mem[i].va + offset;
1403 			break;
1404 		}
1405 	}
1406 
1407 	*seg_id = i;
1408 	return va;
1409 }
1410 
icnss_qdss_trace_save_hdlr(struct icnss_priv * priv,void * data)1411 static int icnss_qdss_trace_save_hdlr(struct icnss_priv *priv,
1412 				      void *data)
1413 {
1414 	struct icnss_qmi_event_qdss_trace_save_data *event_data = data;
1415 	struct icnss_fw_mem *qdss_mem = priv->qdss_mem;
1416 	int ret = 0;
1417 	int i;
1418 	void *va = NULL;
1419 	u64 pa;
1420 	u32 size;
1421 	int seg_id = 0;
1422 
1423 	if (!priv->qdss_mem_seg_len) {
1424 		icnss_pr_err("Memory for QDSS trace is not available\n");
1425 		return -ENOMEM;
1426 	}
1427 
1428 	if (event_data->mem_seg_len == 0) {
1429 		for (i = 0; i < priv->qdss_mem_seg_len; i++) {
1430 			ret = icnss_genl_send_msg(qdss_mem[i].va,
1431 						  ICNSS_GENL_MSG_TYPE_QDSS,
1432 						  event_data->file_name,
1433 						  qdss_mem[i].size);
1434 			if (ret < 0) {
1435 				icnss_pr_err("Fail to save QDSS data: %d\n",
1436 					     ret);
1437 				break;
1438 			}
1439 		}
1440 	} else {
1441 		for (i = 0; i < event_data->mem_seg_len; i++) {
1442 			pa = event_data->mem_seg[i].addr;
1443 			size = event_data->mem_seg[i].size;
1444 			va = icnss_qdss_trace_pa_to_va(priv, pa,
1445 						       size, &seg_id);
1446 			if (!va) {
1447 				icnss_pr_err("Fail to find matching va for pa %pa\n",
1448 					     &pa);
1449 				ret = -EINVAL;
1450 				break;
1451 			}
1452 			ret = icnss_genl_send_msg(va, ICNSS_GENL_MSG_TYPE_QDSS,
1453 						  event_data->file_name, size);
1454 			if (ret < 0) {
1455 				icnss_pr_err("Fail to save QDSS data: %d\n",
1456 					     ret);
1457 				break;
1458 			}
1459 		}
1460 	}
1461 
1462 	kfree(data);
1463 	return ret;
1464 }
1465 
icnss_atomic_dec_if_greater_one(atomic_t * v)1466 static inline int icnss_atomic_dec_if_greater_one(atomic_t *v)
1467 {
1468 	int dec, c = atomic_read(v);
1469 
1470 	do {
1471 		dec = c - 1;
1472 		if (unlikely(dec < 1))
1473 			break;
1474 	} while (!atomic_try_cmpxchg(v, &c, dec));
1475 
1476 	return dec;
1477 }
1478 
icnss_qdss_trace_req_data_hdlr(struct icnss_priv * priv,void * data)1479 static int icnss_qdss_trace_req_data_hdlr(struct icnss_priv *priv,
1480 					  void *data)
1481 {
1482 	int ret = 0;
1483 	struct icnss_qmi_event_qdss_trace_save_data *event_data = data;
1484 
1485 	if (!priv)
1486 		return -ENODEV;
1487 
1488 	if (!data)
1489 		return -EINVAL;
1490 
1491 	ret = icnss_wlfw_qdss_data_send_sync(priv, event_data->file_name,
1492 					     event_data->total_size);
1493 
1494 	kfree(data);
1495 	return ret;
1496 }
1497 
icnss_event_soc_wake_request(struct icnss_priv * priv,void * data)1498 static int icnss_event_soc_wake_request(struct icnss_priv *priv, void *data)
1499 {
1500 	int ret = 0;
1501 
1502 	if (!priv)
1503 		return -ENODEV;
1504 
1505 	if (atomic_inc_not_zero(&priv->soc_wake_ref_count)) {
1506 		icnss_pr_soc_wake("SOC awake after posting work, Ref count: %d",
1507 				  atomic_read(&priv->soc_wake_ref_count));
1508 		return 0;
1509 	}
1510 
1511 	ret = icnss_send_smp2p(priv, ICNSS_SOC_WAKE_REQ,
1512 			       ICNSS_SMP2P_OUT_SOC_WAKE);
1513 	if (!ret)
1514 		atomic_inc(&priv->soc_wake_ref_count);
1515 
1516 	return ret;
1517 }
1518 
icnss_event_soc_wake_release(struct icnss_priv * priv,void * data)1519 static int icnss_event_soc_wake_release(struct icnss_priv *priv, void *data)
1520 {
1521 	int ret = 0;
1522 
1523 	if (!priv)
1524 		return -ENODEV;
1525 
1526 	if (atomic_dec_if_positive(&priv->soc_wake_ref_count)) {
1527 		icnss_pr_soc_wake("Wake release not called. Ref count: %d",
1528 				  priv->soc_wake_ref_count);
1529 		return 0;
1530 	}
1531 
1532 	ret = icnss_send_smp2p(priv, ICNSS_SOC_WAKE_REL,
1533 			       ICNSS_SMP2P_OUT_SOC_WAKE);
1534 	return ret;
1535 }
1536 
icnss_driver_event_register_driver(struct icnss_priv * priv,void * data)1537 static int icnss_driver_event_register_driver(struct icnss_priv *priv,
1538 							 void *data)
1539 {
1540 	int ret = 0;
1541 	int probe_cnt = 0;
1542 
1543 	if (priv->ops)
1544 		return -EEXIST;
1545 
1546 	priv->ops = data;
1547 
1548 	if (test_bit(SKIP_QMI, &priv->ctrl_params.quirks))
1549 		set_bit(ICNSS_FW_READY, &priv->state);
1550 
1551 	if (test_bit(ICNSS_FW_DOWN, &priv->state)) {
1552 		icnss_pr_err("FW is in bad state, state: 0x%lx\n",
1553 			     priv->state);
1554 		return -ENODEV;
1555 	}
1556 
1557 	if (!test_bit(ICNSS_FW_READY, &priv->state)) {
1558 		icnss_pr_dbg("FW is not ready yet, state: 0x%lx\n",
1559 			     priv->state);
1560 		goto out;
1561 	}
1562 
1563 	ret = icnss_hw_power_on(priv);
1564 	if (ret)
1565 		goto out;
1566 
1567 	icnss_block_shutdown(true);
1568 	while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
1569 		ret = priv->ops->probe(&priv->pdev->dev);
1570 		probe_cnt++;
1571 		if (ret != -EPROBE_DEFER)
1572 			break;
1573 	}
1574 	if (ret) {
1575 		icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n",
1576 			     ret, priv->state, probe_cnt);
1577 		icnss_block_shutdown(false);
1578 		goto power_off;
1579 	}
1580 
1581 	icnss_block_shutdown(false);
1582 	set_bit(ICNSS_DRIVER_PROBED, &priv->state);
1583 
1584 	return 0;
1585 
1586 power_off:
1587 	icnss_hw_power_off(priv);
1588 out:
1589 	return ret;
1590 }
1591 
icnss_driver_event_unregister_driver(struct icnss_priv * priv,void * data)1592 static int icnss_driver_event_unregister_driver(struct icnss_priv *priv,
1593 							 void *data)
1594 {
1595 	if (!test_bit(ICNSS_DRIVER_PROBED, &priv->state)) {
1596 		priv->ops = NULL;
1597 		goto out;
1598 	}
1599 
1600 	set_bit(ICNSS_DRIVER_UNLOADING, &priv->state);
1601 
1602 	icnss_block_shutdown(true);
1603 
1604 	if (priv->ops)
1605 		priv->ops->remove(&priv->pdev->dev);
1606 
1607 	icnss_block_shutdown(false);
1608 
1609 	clear_bit(ICNSS_DRIVER_UNLOADING, &priv->state);
1610 	clear_bit(ICNSS_DRIVER_PROBED, &priv->state);
1611 
1612 	priv->ops = NULL;
1613 
1614 	icnss_hw_power_off(priv);
1615 
1616 out:
1617 	return 0;
1618 }
1619 
icnss_fw_crashed(struct icnss_priv * priv,struct icnss_event_pd_service_down_data * event_data)1620 static int icnss_fw_crashed(struct icnss_priv *priv,
1621 			    struct icnss_event_pd_service_down_data *event_data)
1622 {
1623 	struct icnss_uevent_fw_down_data fw_down_data = {0};
1624 
1625 	icnss_pr_dbg("FW crashed, state: 0x%lx\n", priv->state);
1626 
1627 	set_bit(ICNSS_PD_RESTART, &priv->state);
1628 
1629 	icnss_pm_stay_awake(priv);
1630 
1631 	if (test_bit(ICNSS_DRIVER_PROBED, &priv->state) &&
1632 	    test_bit(ICNSS_FW_READY, &priv->state)) {
1633 		clear_bit(ICNSS_FW_READY, &priv->state);
1634 		fw_down_data.crashed = true;
1635 		icnss_call_driver_uevent(priv,
1636 					 ICNSS_UEVENT_FW_DOWN,
1637 					 &fw_down_data);
1638 	}
1639 
1640 	if (event_data && event_data->fw_rejuvenate)
1641 		wlfw_rejuvenate_ack_send_sync_msg(priv);
1642 
1643 	return 0;
1644 }
1645 
icnss_update_hang_event_data(struct icnss_priv * priv,struct icnss_uevent_hang_data * hang_data)1646 int icnss_update_hang_event_data(struct icnss_priv *priv,
1647 				 struct icnss_uevent_hang_data *hang_data)
1648 {
1649 	if (!priv->hang_event_data_va)
1650 		return -EINVAL;
1651 
1652 	priv->hang_event_data = kmemdup(priv->hang_event_data_va,
1653 					priv->hang_event_data_len,
1654 					GFP_ATOMIC);
1655 	if (!priv->hang_event_data)
1656 		return -ENOMEM;
1657 
1658 	// Update the hang event params
1659 	hang_data->hang_event_data = priv->hang_event_data;
1660 	hang_data->hang_event_data_len = priv->hang_event_data_len;
1661 
1662 	return 0;
1663 }
1664 
icnss_send_hang_event_data(struct icnss_priv * priv)1665 int icnss_send_hang_event_data(struct icnss_priv *priv)
1666 {
1667 	struct icnss_uevent_hang_data hang_data = {0};
1668 	int ret = 0xFF;
1669 
1670 	if (priv->early_crash_ind) {
1671 		ret = icnss_update_hang_event_data(priv, &hang_data);
1672 		if (ret)
1673 			icnss_pr_err("Unable to allocate memory for Hang event data\n");
1674 	}
1675 	icnss_call_driver_uevent(priv, ICNSS_UEVENT_HANG_DATA,
1676 				 &hang_data);
1677 
1678 	if (!ret) {
1679 		kfree(priv->hang_event_data);
1680 		priv->hang_event_data = NULL;
1681 	}
1682 
1683 	return 0;
1684 }
1685 
icnss_driver_event_pd_service_down(struct icnss_priv * priv,void * data)1686 static int icnss_driver_event_pd_service_down(struct icnss_priv *priv,
1687 					      void *data)
1688 {
1689 	struct icnss_event_pd_service_down_data *event_data = data;
1690 
1691 	if (!test_bit(ICNSS_WLFW_EXISTS, &priv->state)) {
1692 		icnss_ignore_fw_timeout(false);
1693 		goto out;
1694 	}
1695 
1696 	if (priv->force_err_fatal)
1697 		ICNSS_ASSERT(0);
1698 
1699 	if (priv->device_id == WCN6750_DEVICE_ID ||
1700 	    priv->device_id == WCN6450_DEVICE_ID) {
1701 		icnss_send_smp2p(priv, ICNSS_RESET_MSG,
1702 				 ICNSS_SMP2P_OUT_SOC_WAKE);
1703 		icnss_send_smp2p(priv, ICNSS_RESET_MSG,
1704 				 ICNSS_SMP2P_OUT_EP_POWER_SAVE);
1705 	}
1706 
1707 	if (priv->wpss_supported)
1708 		icnss_send_smp2p(priv, ICNSS_RESET_MSG,
1709 				 ICNSS_SMP2P_OUT_POWER_SAVE);
1710 
1711 	icnss_send_hang_event_data(priv);
1712 
1713 	if (priv->early_crash_ind) {
1714 		icnss_pr_dbg("PD Down ignored as early indication is processed: %d, state: 0x%lx\n",
1715 			     event_data->crashed, priv->state);
1716 		goto out;
1717 	}
1718 
1719 	if (test_bit(ICNSS_PD_RESTART, &priv->state) && event_data->crashed) {
1720 		icnss_fatal_err("PD Down while recovery inprogress, crashed: %d, state: 0x%lx\n",
1721 				event_data->crashed, priv->state);
1722 		if (!priv->allow_recursive_recovery)
1723 			ICNSS_ASSERT(0);
1724 		goto out;
1725 	}
1726 
1727 	if (!test_bit(ICNSS_PD_RESTART, &priv->state))
1728 		icnss_fw_crashed(priv, event_data);
1729 
1730 out:
1731 	kfree(data);
1732 
1733 	return 0;
1734 }
1735 
icnss_driver_event_early_crash_ind(struct icnss_priv * priv,void * data)1736 static int icnss_driver_event_early_crash_ind(struct icnss_priv *priv,
1737 					      void *data)
1738 {
1739 	if (!test_bit(ICNSS_WLFW_EXISTS, &priv->state)) {
1740 		icnss_ignore_fw_timeout(false);
1741 		goto out;
1742 	}
1743 
1744 	priv->early_crash_ind = true;
1745 	icnss_fw_crashed(priv, NULL);
1746 
1747 out:
1748 	kfree(data);
1749 
1750 	return 0;
1751 }
1752 
icnss_driver_event_idle_shutdown(struct icnss_priv * priv,void * data)1753 static int icnss_driver_event_idle_shutdown(struct icnss_priv *priv,
1754 					    void *data)
1755 {
1756 	int ret = 0;
1757 
1758 	if (!priv->ops || !priv->ops->idle_shutdown)
1759 		return 0;
1760 
1761 	if (priv->is_ssr || test_bit(ICNSS_PDR, &priv->state) ||
1762 	    test_bit(ICNSS_REJUVENATE, &priv->state)) {
1763 		icnss_pr_err("SSR/PDR is already in-progress during idle shutdown callback\n");
1764 		ret = -EBUSY;
1765 	} else {
1766 		icnss_pr_dbg("Calling driver idle shutdown, state: 0x%lx\n",
1767 								priv->state);
1768 		icnss_block_shutdown(true);
1769 		ret = priv->ops->idle_shutdown(&priv->pdev->dev);
1770 		icnss_block_shutdown(false);
1771 	}
1772 
1773 	return ret;
1774 }
1775 
icnss_driver_event_idle_restart(struct icnss_priv * priv,void * data)1776 static int icnss_driver_event_idle_restart(struct icnss_priv *priv,
1777 					   void *data)
1778 {
1779 	int ret = 0;
1780 
1781 	if (!priv->ops || !priv->ops->idle_restart)
1782 		return 0;
1783 
1784 	if (priv->is_ssr || test_bit(ICNSS_PDR, &priv->state) ||
1785 	    test_bit(ICNSS_REJUVENATE, &priv->state)) {
1786 		icnss_pr_err("SSR/PDR is already in-progress during idle restart callback\n");
1787 		ret = -EBUSY;
1788 	} else {
1789 		icnss_pr_dbg("Calling driver idle restart, state: 0x%lx\n",
1790 								priv->state);
1791 		icnss_block_shutdown(true);
1792 		ret = priv->ops->idle_restart(&priv->pdev->dev);
1793 		icnss_block_shutdown(false);
1794 	}
1795 
1796 	return ret;
1797 }
1798 
icnss_qdss_trace_free_hdlr(struct icnss_priv * priv)1799 static int icnss_qdss_trace_free_hdlr(struct icnss_priv *priv)
1800 {
1801 	icnss_free_qdss_mem(priv);
1802 
1803 	return 0;
1804 }
1805 
icnss_m3_dump_upload_req_hdlr(struct icnss_priv * priv,void * data)1806 static int icnss_m3_dump_upload_req_hdlr(struct icnss_priv *priv,
1807 					 void *data)
1808 {
1809 	struct icnss_m3_upload_segments_req_data *event_data = data;
1810 	struct qcom_dump_segment segment;
1811 	int i, status = 0, ret = 0;
1812 	struct list_head head;
1813 
1814 	if (!dump_enabled()) {
1815 		icnss_pr_info("Dump collection is not enabled\n");
1816 		return ret;
1817 	}
1818 
1819 	if (IS_ERR_OR_NULL(priv->m3_dump_phyareg) ||
1820 	    IS_ERR_OR_NULL(priv->m3_dump_phydbg) ||
1821 	    IS_ERR_OR_NULL(priv->m3_dump_wmac0reg) ||
1822 	    IS_ERR_OR_NULL(priv->m3_dump_wcssdbg) ||
1823 	    IS_ERR_OR_NULL(priv->m3_dump_phyapdmem))
1824 		return ret;
1825 
1826 	INIT_LIST_HEAD(&head);
1827 
1828 	for (i = 0; i < event_data->no_of_valid_segments; i++) {
1829 		memset(&segment, 0, sizeof(segment));
1830 
1831 		segment.va = devm_ioremap(&priv->pdev->dev,
1832 					  event_data->m3_segment[i].addr,
1833 					  event_data->m3_segment[i].size);
1834 		if (!segment.va) {
1835 			icnss_pr_err("Failed to ioremap M3 Dump region");
1836 			ret = -ENOMEM;
1837 			goto send_resp;
1838 		}
1839 
1840 		segment.size = event_data->m3_segment[i].size;
1841 
1842 		list_add(&segment.node, &head);
1843 		icnss_pr_dbg("Started Dump colletcion for %s segment",
1844 			     event_data->m3_segment[i].name);
1845 
1846 		switch (event_data->m3_segment[i].type) {
1847 		case QMI_M3_SEGMENT_PHYAREG_V01:
1848 			ret = qcom_dump(&head, priv->m3_dump_phyareg->dev);
1849 			break;
1850 		case QMI_M3_SEGMENT_PHYDBG_V01:
1851 			ret = qcom_dump(&head, priv->m3_dump_phydbg->dev);
1852 			break;
1853 		case QMI_M3_SEGMENT_WMAC0_REG_V01:
1854 			ret = qcom_dump(&head, priv->m3_dump_wmac0reg->dev);
1855 			break;
1856 		case QMI_M3_SEGMENT_WCSSDBG_V01:
1857 			ret = qcom_dump(&head, priv->m3_dump_wcssdbg->dev);
1858 			break;
1859 		case QMI_M3_SEGMENT_PHYAPDMEM_V01:
1860 			ret = qcom_dump(&head, priv->m3_dump_phyapdmem->dev);
1861 			break;
1862 		default:
1863 			icnss_pr_err("Invalid Segment type: %d",
1864 				     event_data->m3_segment[i].type);
1865 		}
1866 
1867 		if (ret) {
1868 			status = ret;
1869 			icnss_pr_err("Failed to dump m3 %s segment, err = %d\n",
1870 				     event_data->m3_segment[i].name, ret);
1871 		}
1872 		list_del(&segment.node);
1873 	}
1874 send_resp:
1875 	icnss_wlfw_m3_dump_upload_done_send_sync(priv, event_data->pdev_id,
1876 						 status);
1877 
1878 	return ret;
1879 }
1880 
icnss_subsys_restart_level(struct icnss_priv * priv,void * data)1881 static int icnss_subsys_restart_level(struct icnss_priv *priv, void *data)
1882 {
1883 	int ret = 0;
1884 	struct icnss_subsys_restart_level_data *event_data = data;
1885 
1886 	if (!priv)
1887 		return -ENODEV;
1888 
1889 	if (!data)
1890 		return -EINVAL;
1891 
1892 	ret = wlfw_subsys_restart_level_msg(priv, event_data->restart_level);
1893 
1894 	kfree(data);
1895 
1896 	return ret;
1897 }
1898 
icnss_wpss_self_recovery(struct work_struct * wpss_load_work)1899 static void icnss_wpss_self_recovery(struct work_struct *wpss_load_work)
1900 {
1901 	int ret;
1902 	struct icnss_priv *priv = icnss_get_plat_priv();
1903 
1904 	rproc_shutdown(priv->rproc);
1905 	ret = rproc_boot(priv->rproc);
1906 	if (ret) {
1907 		icnss_pr_err("Failed to self recover wpss rproc, ret: %d", ret);
1908 		rproc_put(priv->rproc);
1909 	}
1910 }
1911 
icnss_driver_event_work(struct work_struct * work)1912 static void icnss_driver_event_work(struct work_struct *work)
1913 {
1914 	struct icnss_priv *priv =
1915 		container_of(work, struct icnss_priv, event_work);
1916 	struct icnss_driver_event *event;
1917 	unsigned long flags;
1918 	int ret;
1919 
1920 	icnss_pm_stay_awake(priv);
1921 
1922 	spin_lock_irqsave(&priv->event_lock, flags);
1923 
1924 	while (!list_empty(&priv->event_list)) {
1925 		event = list_first_entry(&priv->event_list,
1926 					 struct icnss_driver_event, list);
1927 		list_del(&event->list);
1928 		spin_unlock_irqrestore(&priv->event_lock, flags);
1929 
1930 		icnss_pr_dbg("Processing event: %s%s(%d), state: 0x%lx\n",
1931 			     icnss_driver_event_to_str(event->type),
1932 			     event->sync ? "-sync" : "", event->type,
1933 			     priv->state);
1934 
1935 		switch (event->type) {
1936 		case ICNSS_DRIVER_EVENT_SERVER_ARRIVE:
1937 			ret = icnss_driver_event_server_arrive(priv,
1938 								 event->data);
1939 			break;
1940 		case ICNSS_DRIVER_EVENT_SERVER_EXIT:
1941 			ret = icnss_driver_event_server_exit(priv);
1942 			break;
1943 		case ICNSS_DRIVER_EVENT_FW_READY_IND:
1944 			ret = icnss_driver_event_fw_ready_ind(priv,
1945 								 event->data);
1946 			break;
1947 		case ICNSS_DRIVER_EVENT_REGISTER_DRIVER:
1948 			ret = icnss_driver_event_register_driver(priv,
1949 								 event->data);
1950 			break;
1951 		case ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER:
1952 			ret = icnss_driver_event_unregister_driver(priv,
1953 								   event->data);
1954 			break;
1955 		case ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN:
1956 			ret = icnss_driver_event_pd_service_down(priv,
1957 								 event->data);
1958 			break;
1959 		case ICNSS_DRIVER_EVENT_FW_EARLY_CRASH_IND:
1960 			ret = icnss_driver_event_early_crash_ind(priv,
1961 								 event->data);
1962 			break;
1963 		case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
1964 			ret = icnss_driver_event_idle_shutdown(priv,
1965 							       event->data);
1966 			break;
1967 		case ICNSS_DRIVER_EVENT_IDLE_RESTART:
1968 			ret = icnss_driver_event_idle_restart(priv,
1969 							      event->data);
1970 			break;
1971 		case ICNSS_DRIVER_EVENT_FW_INIT_DONE_IND:
1972 			ret = icnss_driver_event_fw_init_done(priv,
1973 							      event->data);
1974 			break;
1975 		case ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM:
1976 			ret = icnss_qdss_trace_req_mem_hdlr(priv);
1977 			break;
1978 		case ICNSS_DRIVER_EVENT_QDSS_TRACE_SAVE:
1979 			ret = icnss_qdss_trace_save_hdlr(priv,
1980 							 event->data);
1981 			break;
1982 		case ICNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
1983 			ret = icnss_qdss_trace_free_hdlr(priv);
1984 			break;
1985 		case ICNSS_DRIVER_EVENT_M3_DUMP_UPLOAD_REQ:
1986 			ret = icnss_m3_dump_upload_req_hdlr(priv, event->data);
1987 			break;
1988 		case ICNSS_DRIVER_EVENT_QDSS_TRACE_REQ_DATA:
1989 			ret = icnss_qdss_trace_req_data_hdlr(priv,
1990 							     event->data);
1991 			break;
1992 		case ICNSS_DRIVER_EVENT_SUBSYS_RESTART_LEVEL:
1993 			ret = icnss_subsys_restart_level(priv, event->data);
1994 			break;
1995 		case ICNSS_DRIVER_EVENT_IMS_WFC_CALL_IND:
1996 			ret = icnss_process_wfc_call_ind_event(priv,
1997 							      event->data);
1998 			break;
1999 		case ICNSS_DRIVER_EVENT_WLFW_TWT_CFG_IND:
2000 			ret = icnss_process_twt_cfg_ind_event(priv,
2001 							     event->data);
2002 			break;
2003 		default:
2004 			icnss_pr_err("Invalid Event type: %d", event->type);
2005 			kfree(event);
2006 			continue;
2007 		}
2008 
2009 		priv->stats.events[event->type].processed++;
2010 
2011 		icnss_pr_dbg("Event Processed: %s%s(%d), ret: %d, state: 0x%lx\n",
2012 			     icnss_driver_event_to_str(event->type),
2013 			     event->sync ? "-sync" : "", event->type, ret,
2014 			     priv->state);
2015 
2016 		spin_lock_irqsave(&priv->event_lock, flags);
2017 		if (event->sync) {
2018 			event->ret = ret;
2019 			complete(&event->complete);
2020 			continue;
2021 		}
2022 		spin_unlock_irqrestore(&priv->event_lock, flags);
2023 
2024 		kfree(event);
2025 
2026 		spin_lock_irqsave(&priv->event_lock, flags);
2027 	}
2028 	spin_unlock_irqrestore(&priv->event_lock, flags);
2029 
2030 	icnss_pm_relax(priv);
2031 }
2032 
icnss_soc_wake_msg_work(struct work_struct * work)2033 static void icnss_soc_wake_msg_work(struct work_struct *work)
2034 {
2035 	struct icnss_priv *priv =
2036 		container_of(work, struct icnss_priv, soc_wake_msg_work);
2037 	struct icnss_soc_wake_event *event;
2038 	unsigned long flags;
2039 	int ret;
2040 
2041 	icnss_pm_stay_awake(priv);
2042 
2043 	spin_lock_irqsave(&priv->soc_wake_msg_lock, flags);
2044 
2045 	while (!list_empty(&priv->soc_wake_msg_list)) {
2046 		event = list_first_entry(&priv->soc_wake_msg_list,
2047 					 struct icnss_soc_wake_event, list);
2048 		list_del(&event->list);
2049 		spin_unlock_irqrestore(&priv->soc_wake_msg_lock, flags);
2050 
2051 		icnss_pr_soc_wake("Processing event: %s%s(%d), state: 0x%lx\n",
2052 				  icnss_soc_wake_event_to_str(event->type),
2053 				  event->sync ? "-sync" : "", event->type,
2054 				  priv->state);
2055 
2056 		switch (event->type) {
2057 		case ICNSS_SOC_WAKE_REQUEST_EVENT:
2058 			ret = icnss_event_soc_wake_request(priv,
2059 							   event->data);
2060 			break;
2061 		case ICNSS_SOC_WAKE_RELEASE_EVENT:
2062 			ret = icnss_event_soc_wake_release(priv,
2063 							   event->data);
2064 			break;
2065 		default:
2066 			icnss_pr_err("Invalid Event type: %d", event->type);
2067 			kfree(event);
2068 			continue;
2069 		}
2070 
2071 		priv->stats.soc_wake_events[event->type].processed++;
2072 
2073 		icnss_pr_soc_wake("Event Processed: %s%s(%d), ret: %d, state: 0x%lx\n",
2074 				  icnss_soc_wake_event_to_str(event->type),
2075 				  event->sync ? "-sync" : "", event->type, ret,
2076 				  priv->state);
2077 
2078 		spin_lock_irqsave(&priv->soc_wake_msg_lock, flags);
2079 		if (event->sync) {
2080 			event->ret = ret;
2081 			complete(&event->complete);
2082 			continue;
2083 		}
2084 		spin_unlock_irqrestore(&priv->soc_wake_msg_lock, flags);
2085 
2086 		kfree(event);
2087 
2088 		spin_lock_irqsave(&priv->soc_wake_msg_lock, flags);
2089 	}
2090 	spin_unlock_irqrestore(&priv->soc_wake_msg_lock, flags);
2091 
2092 	icnss_pm_relax(priv);
2093 }
2094 
icnss_msa0_ramdump(struct icnss_priv * priv)2095 static int icnss_msa0_ramdump(struct icnss_priv *priv)
2096 {
2097 	int ret = 0;
2098 	struct qcom_dump_segment segment;
2099 	struct icnss_ramdump_info *msa0_dump_dev = priv->msa0_dump_dev;
2100 	struct list_head head;
2101 
2102 	if (!dump_enabled()) {
2103 		icnss_pr_info("Dump collection is not enabled\n");
2104 		return ret;
2105 	}
2106 
2107 	if (IS_ERR_OR_NULL(msa0_dump_dev))
2108 		return ret;
2109 
2110 	INIT_LIST_HEAD(&head);
2111 
2112 	memset(&segment, 0, sizeof(segment));
2113 
2114 	segment.va = priv->msa_va;
2115 	segment.size = priv->msa_mem_size;
2116 
2117 	list_add(&segment.node, &head);
2118 
2119 	if (!msa0_dump_dev->dev) {
2120 		icnss_pr_err("Created Dump Device not found\n");
2121 		return 0;
2122 	}
2123 
2124 	ret = qcom_dump(&head, msa0_dump_dev->dev);
2125 	if (ret) {
2126 		icnss_pr_err("Failed to dump msa0, err = %d\n", ret);
2127 		return ret;
2128 	}
2129 
2130 	list_del(&segment.node);
2131 	return ret;
2132 }
2133 
icnss_update_state_send_modem_shutdown(struct icnss_priv * priv,void * data)2134 static void icnss_update_state_send_modem_shutdown(struct icnss_priv *priv,
2135 							void *data)
2136 {
2137 	struct qcom_ssr_notify_data *notif = data;
2138 	int ret = 0;
2139 
2140 	if (!notif->crashed) {
2141 		if (atomic_read(&priv->is_shutdown)) {
2142 			atomic_set(&priv->is_shutdown, false);
2143 			if (!test_bit(ICNSS_PD_RESTART, &priv->state) &&
2144 				!test_bit(ICNSS_SHUTDOWN_DONE, &priv->state) &&
2145 				!test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) {
2146 				clear_bit(ICNSS_FW_READY, &priv->state);
2147 				icnss_driver_event_post(priv,
2148 					  ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
2149 					  ICNSS_EVENT_SYNC_UNINTERRUPTIBLE,
2150 					  NULL);
2151 			}
2152 		}
2153 
2154 		if (test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) {
2155 			if (!wait_for_completion_timeout(
2156 					&priv->unblock_shutdown,
2157 					msecs_to_jiffies(PROBE_TIMEOUT)))
2158 				icnss_pr_err("modem block shutdown timeout\n");
2159 		}
2160 
2161 		ret = wlfw_send_modem_shutdown_msg(priv);
2162 		if (ret < 0)
2163 			icnss_pr_err("Fail to send modem shutdown Indication %d\n",
2164 				     ret);
2165 	}
2166 }
2167 
icnss_qcom_ssr_notify_state_to_str(enum qcom_ssr_notify_type code)2168 static char *icnss_qcom_ssr_notify_state_to_str(enum qcom_ssr_notify_type code)
2169 {
2170 	switch (code) {
2171 	case QCOM_SSR_BEFORE_POWERUP:
2172 		return "BEFORE_POWERUP";
2173 	case QCOM_SSR_AFTER_POWERUP:
2174 		return "AFTER_POWERUP";
2175 	case QCOM_SSR_BEFORE_SHUTDOWN:
2176 		return "BEFORE_SHUTDOWN";
2177 	case QCOM_SSR_AFTER_SHUTDOWN:
2178 		return "AFTER_SHUTDOWN";
2179 	default:
2180 		return "UNKNOWN";
2181 	}
2182 };
2183 
icnss_wpss_early_notifier_nb(struct notifier_block * nb,unsigned long code,void * data)2184 static int icnss_wpss_early_notifier_nb(struct notifier_block *nb,
2185 					unsigned long code,
2186 					void *data)
2187 {
2188 	struct icnss_priv *priv = container_of(nb, struct icnss_priv,
2189 					       wpss_early_ssr_nb);
2190 
2191 	icnss_pr_vdbg("WPSS-EARLY-Notify: event %s(%lu)\n",
2192 		      icnss_qcom_ssr_notify_state_to_str(code), code);
2193 
2194 	if (code == QCOM_SSR_BEFORE_SHUTDOWN) {
2195 		set_bit(ICNSS_FW_DOWN, &priv->state);
2196 		icnss_ignore_fw_timeout(true);
2197 	}
2198 
2199 	return NOTIFY_DONE;
2200 }
2201 
icnss_wpss_notifier_nb(struct notifier_block * nb,unsigned long code,void * data)2202 static int icnss_wpss_notifier_nb(struct notifier_block *nb,
2203 				  unsigned long code,
2204 				  void *data)
2205 {
2206 	struct icnss_event_pd_service_down_data *event_data;
2207 	struct qcom_ssr_notify_data *notif = data;
2208 	struct icnss_priv *priv = container_of(nb, struct icnss_priv,
2209 					       wpss_ssr_nb);
2210 	struct icnss_uevent_fw_down_data fw_down_data = {0};
2211 
2212 	icnss_pr_vdbg("WPSS-Notify: event %s(%lu)\n",
2213 		      icnss_qcom_ssr_notify_state_to_str(code), code);
2214 
2215 	switch (code) {
2216 	case QCOM_SSR_BEFORE_SHUTDOWN:
2217 		break;
2218 	case QCOM_SSR_AFTER_SHUTDOWN:
2219 		/* Collect ramdump only when there was a crash. */
2220 		if (notif->crashed) {
2221 			icnss_pr_info("Collecting msa0 segment dump\n");
2222 			icnss_msa0_ramdump(priv);
2223 		}
2224 		goto out;
2225 	default:
2226 		goto out;
2227 	}
2228 
2229 
2230 	if (priv->wpss_self_recovery_enabled)
2231 		del_timer(&priv->wpss_ssr_timer);
2232 
2233 	priv->is_ssr = true;
2234 
2235 	icnss_pr_info("WPSS went down, state: 0x%lx, crashed: %d\n",
2236 		      priv->state, notif->crashed);
2237 
2238 	if (priv->device_id == ADRASTEA_DEVICE_ID)
2239 		icnss_update_state_send_modem_shutdown(priv, data);
2240 
2241 	set_bit(ICNSS_FW_DOWN, &priv->state);
2242 	icnss_ignore_fw_timeout(true);
2243 
2244 	if (notif->crashed)
2245 		priv->stats.recovery.root_pd_crash++;
2246 	else
2247 		priv->stats.recovery.root_pd_shutdown++;
2248 
2249 	event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
2250 
2251 	if (event_data == NULL)
2252 		return notifier_from_errno(-ENOMEM);
2253 
2254 	event_data->crashed = notif->crashed;
2255 
2256 	fw_down_data.crashed = !!notif->crashed;
2257 	if (test_bit(ICNSS_FW_READY, &priv->state)) {
2258 		clear_bit(ICNSS_FW_READY, &priv->state);
2259 		fw_down_data.crashed = !!notif->crashed;
2260 		icnss_call_driver_uevent(priv,
2261 					 ICNSS_UEVENT_FW_DOWN,
2262 					 &fw_down_data);
2263 	}
2264 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
2265 				ICNSS_EVENT_SYNC, event_data);
2266 
2267 	if (notif->crashed)
2268 		mod_timer(&priv->recovery_timer,
2269 			  jiffies + msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT));
2270 out:
2271 	icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
2272 	return NOTIFY_OK;
2273 }
2274 
icnss_modem_notifier_nb(struct notifier_block * nb,unsigned long code,void * data)2275 static int icnss_modem_notifier_nb(struct notifier_block *nb,
2276 				  unsigned long code,
2277 				  void *data)
2278 {
2279 	struct icnss_event_pd_service_down_data *event_data;
2280 	struct qcom_ssr_notify_data *notif = data;
2281 	struct icnss_priv *priv = container_of(nb, struct icnss_priv,
2282 					       modem_ssr_nb);
2283 	struct icnss_uevent_fw_down_data fw_down_data = {0};
2284 
2285 	icnss_pr_vdbg("Modem-Notify: event %s(%lu)\n",
2286 		      icnss_qcom_ssr_notify_state_to_str(code), code);
2287 
2288 	switch (code) {
2289 	case QCOM_SSR_BEFORE_SHUTDOWN:
2290 		if (priv->is_slate_rfa)
2291 			complete(&priv->slate_boot_complete);
2292 
2293 		if (!notif->crashed &&
2294 		    priv->low_power_support) { /* Hibernate */
2295 			if (test_bit(ICNSS_MODE_ON, &priv->state))
2296 				icnss_driver_event_post(
2297 					priv, ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
2298 					ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
2299 			set_bit(ICNSS_LOW_POWER, &priv->state);
2300 		}
2301 		break;
2302 	case QCOM_SSR_AFTER_SHUTDOWN:
2303 		/* Collect ramdump only when there was a crash. */
2304 		if (notif->crashed) {
2305 			icnss_pr_info("Collecting msa0 segment dump\n");
2306 			icnss_msa0_ramdump(priv);
2307 		}
2308 
2309 		goto out;
2310 	default:
2311 		goto out;
2312 	}
2313 
2314 	priv->is_ssr = true;
2315 
2316 	if (notif->crashed) {
2317 		priv->stats.recovery.root_pd_crash++;
2318 		priv->root_pd_shutdown = false;
2319 	} else {
2320 		priv->stats.recovery.root_pd_shutdown++;
2321 		priv->root_pd_shutdown = true;
2322 	}
2323 
2324 	icnss_update_state_send_modem_shutdown(priv, data);
2325 
2326 	if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
2327 		set_bit(ICNSS_FW_DOWN, &priv->state);
2328 		icnss_ignore_fw_timeout(true);
2329 
2330 		if (test_bit(ICNSS_FW_READY, &priv->state)) {
2331 			clear_bit(ICNSS_FW_READY, &priv->state);
2332 			fw_down_data.crashed = !!notif->crashed;
2333 			icnss_call_driver_uevent(priv,
2334 						 ICNSS_UEVENT_FW_DOWN,
2335 						 &fw_down_data);
2336 		}
2337 		goto out;
2338 	}
2339 
2340 	icnss_pr_info("Modem went down, state: 0x%lx, crashed: %d\n",
2341 		      priv->state, notif->crashed);
2342 
2343 	set_bit(ICNSS_FW_DOWN, &priv->state);
2344 
2345 	icnss_ignore_fw_timeout(true);
2346 
2347 	event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
2348 
2349 	if (event_data == NULL)
2350 		return notifier_from_errno(-ENOMEM);
2351 
2352 	event_data->crashed = notif->crashed;
2353 
2354 	fw_down_data.crashed = !!notif->crashed;
2355 	if (test_bit(ICNSS_FW_READY, &priv->state)) {
2356 		clear_bit(ICNSS_FW_READY, &priv->state);
2357 		fw_down_data.crashed = !!notif->crashed;
2358 		icnss_call_driver_uevent(priv,
2359 					 ICNSS_UEVENT_FW_DOWN,
2360 					 &fw_down_data);
2361 	}
2362 	icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
2363 				ICNSS_EVENT_SYNC, event_data);
2364 
2365 	if (notif->crashed)
2366 		mod_timer(&priv->recovery_timer,
2367 			  jiffies + msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT));
2368 out:
2369 	icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
2370 	return NOTIFY_OK;
2371 }
2372 
icnss_wpss_early_ssr_register_notifier(struct icnss_priv * priv)2373 static int icnss_wpss_early_ssr_register_notifier(struct icnss_priv *priv)
2374 {
2375 	int ret = 0;
2376 
2377 	priv->wpss_early_ssr_nb.notifier_call = icnss_wpss_early_notifier_nb;
2378 
2379 	priv->wpss_early_notify_handler =
2380 		qcom_register_early_ssr_notifier("wpss",
2381 						 &priv->wpss_early_ssr_nb);
2382 
2383 	if (IS_ERR_OR_NULL(priv->wpss_early_notify_handler)) {
2384 		ret = PTR_ERR(priv->wpss_early_notify_handler);
2385 		icnss_pr_err("WPSS register early notifier failed: %d\n", ret);
2386 	}
2387 
2388 	return ret;
2389 }
2390 
icnss_wpss_ssr_register_notifier(struct icnss_priv * priv)2391 static int icnss_wpss_ssr_register_notifier(struct icnss_priv *priv)
2392 {
2393 	int ret = 0;
2394 
2395 	priv->wpss_ssr_nb.notifier_call = icnss_wpss_notifier_nb;
2396 	/*
2397 	 * Assign priority of icnss wpss notifier callback over IPA
2398 	 * modem notifier callback which is 0
2399 	 */
2400 	priv->wpss_ssr_nb.priority = 1;
2401 
2402 	priv->wpss_notify_handler =
2403 		qcom_register_ssr_notifier("wpss", &priv->wpss_ssr_nb);
2404 
2405 	if (IS_ERR_OR_NULL(priv->wpss_notify_handler)) {
2406 		ret = PTR_ERR(priv->wpss_notify_handler);
2407 		icnss_pr_err("WPSS register notifier failed: %d\n", ret);
2408 	}
2409 
2410 	set_bit(ICNSS_SSR_REGISTERED, &priv->state);
2411 
2412 	return ret;
2413 }
2414 
2415 #ifdef CONFIG_SLATE_MODULE_ENABLED
icnss_slate_event_notifier_nb(struct notifier_block * nb,unsigned long event,void * data)2416 static int icnss_slate_event_notifier_nb(struct notifier_block *nb,
2417 					 unsigned long event, void *data)
2418 {
2419 	icnss_pr_info("Received slate event 0x%x\n", event);
2420 
2421 	if (event == SLATE_STATUS) {
2422 		struct icnss_priv *priv = container_of(nb, struct icnss_priv,
2423 						       seb_nb);
2424 		enum boot_status status = *(enum boot_status *)data;
2425 
2426 		if (status == SLATE_READY) {
2427 			icnss_pr_dbg("Slate ready received, state: 0x%lx\n",
2428 				     priv->state);
2429 			set_bit(ICNSS_SLATE_READY, &priv->state);
2430 			set_bit(ICNSS_SLATE_UP, &priv->state);
2431 			complete(&priv->slate_boot_complete);
2432 		}
2433 	}
2434 
2435 	return NOTIFY_OK;
2436 }
2437 
icnss_register_slate_event_notifier(struct icnss_priv * priv)2438 static int icnss_register_slate_event_notifier(struct icnss_priv *priv)
2439 {
2440 	int ret = 0;
2441 
2442 	priv->seb_nb.notifier_call = icnss_slate_event_notifier_nb;
2443 
2444 	priv->seb_handle = seb_register_for_slate_event(SLATE_STATUS,
2445 							&priv->seb_nb);
2446 	if (IS_ERR_OR_NULL(priv->seb_handle)) {
2447 		ret = priv->seb_handle ? PTR_ERR(priv->seb_handle) : -EINVAL;
2448 		icnss_pr_err("SLATE event register notifier failed: %d\n",
2449 			     ret);
2450 	}
2451 
2452 	return ret;
2453 }
2454 
icnss_unregister_slate_event_notifier(struct icnss_priv * priv)2455 static int icnss_unregister_slate_event_notifier(struct icnss_priv *priv)
2456 {
2457 	int ret = 0;
2458 
2459 	ret = seb_unregister_for_slate_event(priv->seb_handle, &priv->seb_nb);
2460 	if (ret < 0)
2461 		icnss_pr_err("Slate event unregister failed: %d\n", ret);
2462 
2463 	return ret;
2464 }
2465 
icnss_slate_notifier_nb(struct notifier_block * nb,unsigned long code,void * data)2466 static int icnss_slate_notifier_nb(struct notifier_block *nb,
2467 				   unsigned long code,
2468 				   void *data)
2469 {
2470 	struct icnss_priv *priv = container_of(nb, struct icnss_priv,
2471 					       slate_ssr_nb);
2472 	int ret = 0;
2473 
2474 	icnss_pr_vdbg("Slate-subsys-notify: event %lu\n", code);
2475 
2476 	if (code == QCOM_SSR_AFTER_POWERUP &&
2477 	    test_bit(ICNSS_SLATE_READY, &priv->state)) {
2478 		set_bit(ICNSS_SLATE_UP, &priv->state);
2479 		complete(&priv->slate_boot_complete);
2480 		icnss_pr_dbg("Slate boot complete, state: 0x%lx\n",
2481 			     priv->state);
2482 	} else if (code == QCOM_SSR_BEFORE_SHUTDOWN &&
2483 		   test_bit(ICNSS_SLATE_UP, &priv->state)) {
2484 		clear_bit(ICNSS_SLATE_UP, &priv->state);
2485 		if (test_bit(ICNSS_PD_RESTART, &priv->state)) {
2486 			icnss_pr_err("PD_RESTART in progress 0x%lx\n",
2487 				     priv->state);
2488 			goto skip_pdr;
2489 		}
2490 
2491 		icnss_pr_dbg("Initiating PDR 0x%lx\n", priv->state);
2492 		ret = icnss_trigger_recovery(&priv->pdev->dev);
2493 		if (ret < 0) {
2494 			icnss_fatal_err("Fail to trigger PDR: ret: %d, state: 0x%lx\n",
2495 					ret, priv->state);
2496 			goto skip_pdr;
2497 		}
2498 	}
2499 
2500 skip_pdr:
2501 	return NOTIFY_OK;
2502 }
2503 
icnss_slate_ssr_register_notifier(struct icnss_priv * priv)2504 static int icnss_slate_ssr_register_notifier(struct icnss_priv *priv)
2505 {
2506 	int ret = 0;
2507 
2508 	priv->slate_ssr_nb.notifier_call = icnss_slate_notifier_nb;
2509 
2510 	priv->slate_notify_handler =
2511 		qcom_register_ssr_notifier("slatefw", &priv->slate_ssr_nb);
2512 
2513 	if (IS_ERR_OR_NULL(priv->slate_notify_handler)) {
2514 		ret = PTR_ERR(priv->slate_notify_handler);
2515 		icnss_pr_err("SLATE register notifier failed: %d\n", ret);
2516 	}
2517 
2518 	set_bit(ICNSS_SLATE_SSR_REGISTERED, &priv->state);
2519 
2520 	return ret;
2521 }
2522 
icnss_slate_ssr_unregister_notifier(struct icnss_priv * priv)2523 static int icnss_slate_ssr_unregister_notifier(struct icnss_priv *priv)
2524 {
2525 	if (!test_and_clear_bit(ICNSS_SLATE_SSR_REGISTERED, &priv->state))
2526 		return 0;
2527 
2528 	qcom_unregister_ssr_notifier(priv->slate_notify_handler,
2529 				     &priv->slate_ssr_nb);
2530 	priv->slate_notify_handler = NULL;
2531 
2532 	return 0;
2533 }
2534 #else
icnss_register_slate_event_notifier(struct icnss_priv * priv)2535 static int icnss_register_slate_event_notifier(struct icnss_priv *priv)
2536 {
2537 	return 0;
2538 }
2539 
icnss_unregister_slate_event_notifier(struct icnss_priv * priv)2540 static int icnss_unregister_slate_event_notifier(struct icnss_priv *priv)
2541 {
2542 	return 0;
2543 }
2544 
icnss_slate_ssr_register_notifier(struct icnss_priv * priv)2545 static int icnss_slate_ssr_register_notifier(struct icnss_priv *priv)
2546 {
2547 	return 0;
2548 }
2549 
icnss_slate_ssr_unregister_notifier(struct icnss_priv * priv)2550 static int icnss_slate_ssr_unregister_notifier(struct icnss_priv *priv)
2551 {
2552 	return 0;
2553 }
2554 #endif
2555 
icnss_modem_ssr_register_notifier(struct icnss_priv * priv)2556 static int icnss_modem_ssr_register_notifier(struct icnss_priv *priv)
2557 {
2558 	int ret = 0;
2559 
2560 	priv->modem_ssr_nb.notifier_call = icnss_modem_notifier_nb;
2561 	/*
2562 	 * Assign priority of icnss modem notifier callback over IPA
2563 	 * modem notifier callback which is 0
2564 	 */
2565 	priv->modem_ssr_nb.priority = 1;
2566 
2567 	priv->modem_notify_handler =
2568 		qcom_register_ssr_notifier("mpss", &priv->modem_ssr_nb);
2569 
2570 	if (IS_ERR_OR_NULL(priv->modem_notify_handler)) {
2571 		ret = PTR_ERR(priv->modem_notify_handler);
2572 		icnss_pr_err("Modem register notifier failed: %d\n", ret);
2573 	}
2574 
2575 	set_bit(ICNSS_SSR_REGISTERED, &priv->state);
2576 
2577 	return ret;
2578 }
2579 
icnss_wpss_early_ssr_unregister_notifier(struct icnss_priv * priv)2580 static void icnss_wpss_early_ssr_unregister_notifier(struct icnss_priv *priv)
2581 {
2582 	if (IS_ERR_OR_NULL(priv->wpss_early_notify_handler))
2583 		return;
2584 
2585 	qcom_unregister_early_ssr_notifier(priv->wpss_early_notify_handler,
2586 					   &priv->wpss_early_ssr_nb);
2587 	priv->wpss_early_notify_handler = NULL;
2588 }
2589 
icnss_wpss_ssr_unregister_notifier(struct icnss_priv * priv)2590 static int icnss_wpss_ssr_unregister_notifier(struct icnss_priv *priv)
2591 {
2592 	if (!test_and_clear_bit(ICNSS_SSR_REGISTERED, &priv->state))
2593 		return 0;
2594 
2595 	qcom_unregister_ssr_notifier(priv->wpss_notify_handler,
2596 				     &priv->wpss_ssr_nb);
2597 	priv->wpss_notify_handler = NULL;
2598 
2599 	return 0;
2600 }
2601 
icnss_modem_ssr_unregister_notifier(struct icnss_priv * priv)2602 static int icnss_modem_ssr_unregister_notifier(struct icnss_priv *priv)
2603 {
2604 	if (!test_and_clear_bit(ICNSS_SSR_REGISTERED, &priv->state))
2605 		return 0;
2606 
2607 	qcom_unregister_ssr_notifier(priv->modem_notify_handler,
2608 				     &priv->modem_ssr_nb);
2609 	priv->modem_notify_handler = NULL;
2610 
2611 	return 0;
2612 }
2613 
icnss_pdr_notifier_cb(int state,char * service_path,void * priv_cb)2614 static void icnss_pdr_notifier_cb(int state, char *service_path, void *priv_cb)
2615 {
2616 	struct icnss_priv *priv = priv_cb;
2617 	struct icnss_event_pd_service_down_data *event_data;
2618 	struct icnss_uevent_fw_down_data fw_down_data = {0};
2619 	enum icnss_pdr_cause_index cause = ICNSS_ROOT_PD_CRASH;
2620 
2621 	if (!priv)
2622 		return;
2623 
2624 	icnss_pr_dbg("PD service notification: 0x%lx state: 0x%lx\n",
2625 		     state, priv->state);
2626 
2627 	switch (state) {
2628 	case SERVREG_SERVICE_STATE_DOWN:
2629 		event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
2630 
2631 		if (!event_data)
2632 			return;
2633 
2634 		event_data->crashed = true;
2635 
2636 		if (!priv->is_ssr) {
2637 			set_bit(ICNSS_PDR, &penv->state);
2638 			if (test_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state)) {
2639 				cause = ICNSS_HOST_ERROR;
2640 				priv->stats.recovery.pdr_host_error++;
2641 			} else {
2642 				cause = ICNSS_FW_CRASH;
2643 				priv->stats.recovery.pdr_fw_crash++;
2644 			}
2645 		} else if (priv->root_pd_shutdown) {
2646 			cause = ICNSS_ROOT_PD_SHUTDOWN;
2647 			event_data->crashed = false;
2648 		}
2649 
2650 		icnss_pr_info("PD service down, state: 0x%lx: cause: %s\n",
2651 			      priv->state, icnss_pdr_cause[cause]);
2652 
2653 		if (!test_bit(ICNSS_FW_DOWN, &priv->state)) {
2654 			set_bit(ICNSS_FW_DOWN, &priv->state);
2655 			icnss_ignore_fw_timeout(true);
2656 
2657 			if (test_bit(ICNSS_FW_READY, &priv->state)) {
2658 				clear_bit(ICNSS_FW_READY, &priv->state);
2659 				fw_down_data.crashed = event_data->crashed;
2660 				icnss_call_driver_uevent(priv,
2661 							 ICNSS_UEVENT_FW_DOWN,
2662 							 &fw_down_data);
2663 			}
2664 		}
2665 		clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
2666 
2667 		if (event_data->crashed)
2668 			mod_timer(&priv->recovery_timer,
2669 				  jiffies +
2670 				  msecs_to_jiffies(ICNSS_RECOVERY_TIMEOUT));
2671 
2672 		icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
2673 					ICNSS_EVENT_SYNC, event_data);
2674 		break;
2675 	case SERVREG_SERVICE_STATE_UP:
2676 		clear_bit(ICNSS_FW_DOWN, &priv->state);
2677 		break;
2678 	default:
2679 		break;
2680 	}
2681 	return;
2682 }
2683 
icnss_pd_restart_enable(struct icnss_priv * priv)2684 static int icnss_pd_restart_enable(struct icnss_priv *priv)
2685 {
2686 	struct pdr_handle *handle = NULL;
2687 	struct pdr_service *service = NULL;
2688 	int err = 0;
2689 
2690 	handle = pdr_handle_alloc(icnss_pdr_notifier_cb, priv);
2691 	if (IS_ERR_OR_NULL(handle)) {
2692 		err = PTR_ERR(handle);
2693 		icnss_pr_err("Failed to alloc pdr handle, err %d", err);
2694 		goto out;
2695 	}
2696 	service = pdr_add_lookup(handle, ICNSS_WLAN_SERVICE_NAME, ICNSS_WLANPD_NAME);
2697 	if (IS_ERR_OR_NULL(service)) {
2698 		err = PTR_ERR(service);
2699 		icnss_pr_err("Failed to add lookup, err %d", err);
2700 		goto out;
2701 	}
2702 	priv->pdr_handle = handle;
2703 	priv->pdr_service = service;
2704 	set_bit(ICNSS_PDR_REGISTERED, &priv->state);
2705 
2706 	icnss_pr_info("PDR registration happened");
2707 out:
2708 	return err;
2709 }
2710 
icnss_pdr_unregister_notifier(struct icnss_priv * priv)2711 static void icnss_pdr_unregister_notifier(struct icnss_priv *priv)
2712 {
2713 	if (!test_and_clear_bit(ICNSS_PDR_REGISTERED, &priv->state))
2714 		return;
2715 
2716 	pdr_handle_release(priv->pdr_handle);
2717 }
2718 
icnss_ramdump_devnode_init(struct icnss_priv * priv)2719 static int icnss_ramdump_devnode_init(struct icnss_priv *priv)
2720 {
2721 	int ret = 0;
2722 
2723 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0))
2724 	priv->icnss_ramdump_class = class_create(THIS_MODULE, ICNSS_RAMDUMP_NAME);
2725 #else
2726 	priv->icnss_ramdump_class = class_create(ICNSS_RAMDUMP_NAME);
2727 #endif
2728 	if (IS_ERR_OR_NULL(priv->icnss_ramdump_class)) {
2729 		ret = PTR_ERR(priv->icnss_ramdump_class);
2730 		icnss_pr_err("%s:Class create failed for ramdump devices (%d)\n", __func__, ret);
2731 		return ret;
2732 	}
2733 
2734 	ret = alloc_chrdev_region(&priv->icnss_ramdump_dev, 0, RAMDUMP_NUM_DEVICES,
2735 				  ICNSS_RAMDUMP_NAME);
2736 	if (ret < 0) {
2737 		icnss_pr_err("%s: Unable to allocate major\n", __func__);
2738 		goto fail_alloc_major;
2739 	}
2740 	return 0;
2741 
2742 fail_alloc_major:
2743 	class_destroy(priv->icnss_ramdump_class);
2744 	return ret;
2745 }
2746 
icnss_create_ramdump_device(struct icnss_priv * priv,const char * dev_name)2747 void *icnss_create_ramdump_device(struct icnss_priv *priv, const char *dev_name)
2748 {
2749 	int ret = 0;
2750 	struct icnss_ramdump_info *ramdump_info;
2751 
2752 	ramdump_info = kzalloc(sizeof(*ramdump_info), GFP_KERNEL);
2753 	if (!ramdump_info)
2754 		return ERR_PTR(-ENOMEM);
2755 
2756 	if (!dev_name) {
2757 		icnss_pr_err("%s: Invalid device name.\n", __func__);
2758 		return NULL;
2759 	}
2760 
2761 	snprintf(ramdump_info->name, ARRAY_SIZE(ramdump_info->name), "icnss_%s", dev_name);
2762 
2763 	ramdump_info->minor = ida_simple_get(&rd_minor_id, 0, RAMDUMP_NUM_DEVICES, GFP_KERNEL);
2764 	if (ramdump_info->minor < 0) {
2765 		icnss_pr_err("%s: No more minor numbers left! rc:%d\n", __func__,
2766 			     ramdump_info->minor);
2767 		ret = -ENODEV;
2768 		goto fail_out_of_minors;
2769 	}
2770 
2771 	ramdump_info->dev = device_create(priv->icnss_ramdump_class, NULL,
2772 					  MKDEV(MAJOR(priv->icnss_ramdump_dev),
2773 					  ramdump_info->minor),
2774 					  ramdump_info, ramdump_info->name);
2775 	if (IS_ERR_OR_NULL(ramdump_info->dev)) {
2776 		ret = PTR_ERR(ramdump_info->dev);
2777 		icnss_pr_err("%s: Device create failed for %s (%d)\n", __func__,
2778 			     ramdump_info->name, ret);
2779 		goto fail_device_create;
2780 	}
2781 	return (void *)ramdump_info;
2782 
2783 fail_device_create:
2784 	ida_simple_remove(&rd_minor_id, ramdump_info->minor);
2785 fail_out_of_minors:
2786 	kfree(ramdump_info);
2787 	return ERR_PTR(ret);
2788 }
2789 
icnss_register_ramdump_devices(struct icnss_priv * priv)2790 static int icnss_register_ramdump_devices(struct icnss_priv *priv)
2791 {
2792 	int ret = 0;
2793 
2794 	if (!priv || !priv->pdev) {
2795 		icnss_pr_err("Platform priv or pdev is NULL\n");
2796 		return -EINVAL;
2797 	}
2798 
2799 	ret = icnss_ramdump_devnode_init(priv);
2800 	if (ret)
2801 		return ret;
2802 
2803 	priv->msa0_dump_dev = icnss_create_ramdump_device(priv, "wcss_msa0");
2804 
2805 	if (IS_ERR_OR_NULL(priv->msa0_dump_dev) || !priv->msa0_dump_dev->dev) {
2806 		icnss_pr_err("Failed to create msa0 dump device!");
2807 		return -ENOMEM;
2808 	}
2809 
2810 	if (priv->device_id == WCN6750_DEVICE_ID ||
2811 	    priv->device_id == WCN6450_DEVICE_ID) {
2812 		priv->m3_dump_phyareg = icnss_create_ramdump_device(priv,
2813 						ICNSS_M3_SEGMENT(
2814 						ICNSS_M3_SEGMENT_PHYAREG));
2815 
2816 		if (IS_ERR_OR_NULL(priv->m3_dump_phyareg) ||
2817 		    !priv->m3_dump_phyareg->dev) {
2818 			icnss_pr_err("Failed to create m3 dump for Phyareg segment device!");
2819 			return -ENOMEM;
2820 		}
2821 
2822 		priv->m3_dump_phydbg = icnss_create_ramdump_device(priv,
2823 						ICNSS_M3_SEGMENT(
2824 						ICNSS_M3_SEGMENT_PHYA));
2825 
2826 		if (IS_ERR_OR_NULL(priv->m3_dump_phydbg) ||
2827 		    !priv->m3_dump_phydbg->dev) {
2828 			icnss_pr_err("Failed to create m3 dump for Phydbg segment device!");
2829 			return -ENOMEM;
2830 		}
2831 
2832 		priv->m3_dump_wmac0reg = icnss_create_ramdump_device(priv,
2833 						ICNSS_M3_SEGMENT(
2834 						ICNSS_M3_SEGMENT_WMACREG));
2835 
2836 		if (IS_ERR_OR_NULL(priv->m3_dump_wmac0reg) ||
2837 		    !priv->m3_dump_wmac0reg->dev) {
2838 			icnss_pr_err("Failed to create m3 dump for Wmac0reg segment device!");
2839 			return -ENOMEM;
2840 		}
2841 
2842 		priv->m3_dump_wcssdbg = icnss_create_ramdump_device(priv,
2843 						ICNSS_M3_SEGMENT(
2844 						ICNSS_M3_SEGMENT_WCSSDBG));
2845 
2846 		if (IS_ERR_OR_NULL(priv->m3_dump_wcssdbg) ||
2847 		    !priv->m3_dump_wcssdbg->dev) {
2848 			icnss_pr_err("Failed to create m3 dump for Wcssdbg segment device!");
2849 			return -ENOMEM;
2850 		}
2851 
2852 		priv->m3_dump_phyapdmem = icnss_create_ramdump_device(priv,
2853 						ICNSS_M3_SEGMENT(
2854 						ICNSS_M3_SEGMENT_PHYAM3));
2855 
2856 		if (IS_ERR_OR_NULL(priv->m3_dump_phyapdmem) ||
2857 		    !priv->m3_dump_phyapdmem->dev) {
2858 			icnss_pr_err("Failed to create m3 dump for Phyapdmem segment device!");
2859 			return -ENOMEM;
2860 		}
2861 	}
2862 
2863 	return 0;
2864 }
2865 
icnss_enable_recovery(struct icnss_priv * priv)2866 static int icnss_enable_recovery(struct icnss_priv *priv)
2867 {
2868 	int ret;
2869 
2870 	if (test_bit(RECOVERY_DISABLE, &priv->ctrl_params.quirks)) {
2871 		icnss_pr_dbg("Recovery disabled through module parameter\n");
2872 		return 0;
2873 	}
2874 
2875 	if (test_bit(PDR_ONLY, &priv->ctrl_params.quirks)) {
2876 		icnss_pr_dbg("SSR disabled through module parameter\n");
2877 		goto enable_pdr;
2878 	}
2879 
2880 	ret = icnss_register_ramdump_devices(priv);
2881 	if (ret)
2882 		return ret;
2883 
2884 	if (priv->wpss_supported) {
2885 		icnss_wpss_early_ssr_register_notifier(priv);
2886 		icnss_wpss_ssr_register_notifier(priv);
2887 		return 0;
2888 	}
2889 
2890 	if (!(priv->rproc_fw_download))
2891 		icnss_modem_ssr_register_notifier(priv);
2892 
2893 	if (priv->is_slate_rfa) {
2894 		icnss_slate_ssr_register_notifier(priv);
2895 		icnss_register_slate_event_notifier(priv);
2896 	}
2897 
2898 	if (test_bit(SSR_ONLY, &priv->ctrl_params.quirks)) {
2899 		icnss_pr_dbg("PDR disabled through module parameter\n");
2900 		return 0;
2901 	}
2902 
2903 enable_pdr:
2904 	ret = icnss_pd_restart_enable(priv);
2905 
2906 	if (ret)
2907 		return ret;
2908 
2909 	return 0;
2910 }
2911 
icnss_dev_id_match(struct icnss_priv * priv,struct device_info * dev_info)2912 static int icnss_dev_id_match(struct icnss_priv *priv,
2913 			      struct device_info *dev_info)
2914 {
2915 	while (dev_info->device_id) {
2916 		if (priv->device_id == dev_info->device_id)
2917 			return 1;
2918 		dev_info++;
2919 	}
2920 	return 0;
2921 }
2922 
icnss_tcdev_get_max_state(struct thermal_cooling_device * tcdev,unsigned long * thermal_state)2923 static int icnss_tcdev_get_max_state(struct thermal_cooling_device *tcdev,
2924 					unsigned long *thermal_state)
2925 {
2926 	struct icnss_thermal_cdev *icnss_tcdev = tcdev->devdata;
2927 
2928 	*thermal_state = icnss_tcdev->max_thermal_state;
2929 
2930 	return 0;
2931 }
2932 
icnss_tcdev_get_cur_state(struct thermal_cooling_device * tcdev,unsigned long * thermal_state)2933 static int icnss_tcdev_get_cur_state(struct thermal_cooling_device *tcdev,
2934 					unsigned long *thermal_state)
2935 {
2936 	struct icnss_thermal_cdev *icnss_tcdev = tcdev->devdata;
2937 
2938 	*thermal_state = icnss_tcdev->curr_thermal_state;
2939 
2940 	return 0;
2941 }
2942 
icnss_tcdev_set_cur_state(struct thermal_cooling_device * tcdev,unsigned long thermal_state)2943 static int icnss_tcdev_set_cur_state(struct thermal_cooling_device *tcdev,
2944 					unsigned long thermal_state)
2945 {
2946 	struct icnss_thermal_cdev *icnss_tcdev = tcdev->devdata;
2947 	struct device *dev = &penv->pdev->dev;
2948 	int ret = 0;
2949 
2950 
2951 	if (!penv->ops || !penv->ops->set_therm_cdev_state)
2952 		return 0;
2953 
2954 	if (thermal_state > icnss_tcdev->max_thermal_state)
2955 		return -EINVAL;
2956 
2957 	icnss_pr_vdbg("Cooling device set current state: %ld,for cdev id %d",
2958 		      thermal_state, icnss_tcdev->tcdev_id);
2959 
2960 	mutex_lock(&penv->tcdev_lock);
2961 	ret = penv->ops->set_therm_cdev_state(dev, thermal_state,
2962 					      icnss_tcdev->tcdev_id);
2963 	if (!ret)
2964 		icnss_tcdev->curr_thermal_state = thermal_state;
2965 	mutex_unlock(&penv->tcdev_lock);
2966 	if (ret) {
2967 		icnss_pr_err("Setting Current Thermal State Failed: %d,for cdev id %d",
2968 			     ret, icnss_tcdev->tcdev_id);
2969 		return ret;
2970 	}
2971 
2972 	return 0;
2973 }
2974 
2975 static struct thermal_cooling_device_ops icnss_cooling_ops = {
2976 	.get_max_state = icnss_tcdev_get_max_state,
2977 	.get_cur_state = icnss_tcdev_get_cur_state,
2978 	.set_cur_state = icnss_tcdev_set_cur_state,
2979 };
2980 
icnss_thermal_cdev_register(struct device * dev,unsigned long max_state,int tcdev_id)2981 int icnss_thermal_cdev_register(struct device *dev, unsigned long max_state,
2982 			   int tcdev_id)
2983 {
2984 	struct icnss_priv *priv = dev_get_drvdata(dev);
2985 	struct icnss_thermal_cdev *icnss_tcdev = NULL;
2986 	char cdev_node_name[THERMAL_NAME_LENGTH] = "";
2987 	struct device_node *dev_node;
2988 	int ret = 0;
2989 
2990 	icnss_tcdev = kzalloc(sizeof(*icnss_tcdev), GFP_KERNEL);
2991 	if (!icnss_tcdev)
2992 		return -ENOMEM;
2993 
2994 	icnss_tcdev->tcdev_id = tcdev_id;
2995 	icnss_tcdev->max_thermal_state = max_state;
2996 
2997 	snprintf(cdev_node_name, THERMAL_NAME_LENGTH,
2998 		 "qcom,icnss_cdev%d", tcdev_id);
2999 
3000 	dev_node = of_find_node_by_name(NULL, cdev_node_name);
3001 	if (!dev_node) {
3002 		icnss_pr_err("Failed to get cooling device node\n");
3003 		return -EINVAL;
3004 	}
3005 
3006 	icnss_pr_dbg("tcdev node->name=%s\n", dev_node->name);
3007 
3008 	if (of_find_property(dev_node, "#cooling-cells", NULL)) {
3009 		icnss_tcdev->tcdev = thermal_of_cooling_device_register(
3010 						dev_node,
3011 						cdev_node_name, icnss_tcdev,
3012 						&icnss_cooling_ops);
3013 		if (IS_ERR_OR_NULL(icnss_tcdev->tcdev)) {
3014 			ret = PTR_ERR(icnss_tcdev->tcdev);
3015 			icnss_pr_err("Cooling device register failed: %d, for cdev id %d\n",
3016 				     ret, icnss_tcdev->tcdev_id);
3017 		} else {
3018 			icnss_pr_dbg("Cooling device registered for cdev id %d",
3019 				     icnss_tcdev->tcdev_id);
3020 			list_add(&icnss_tcdev->tcdev_list,
3021 				 &priv->icnss_tcdev_list);
3022 		}
3023 	} else {
3024 		icnss_pr_dbg("Cooling device registration not supported");
3025 		ret = -EOPNOTSUPP;
3026 	}
3027 
3028 	return ret;
3029 }
3030 EXPORT_SYMBOL(icnss_thermal_cdev_register);
3031 
icnss_thermal_cdev_unregister(struct device * dev,int tcdev_id)3032 void icnss_thermal_cdev_unregister(struct device *dev, int tcdev_id)
3033 {
3034 	struct icnss_priv *priv = dev_get_drvdata(dev);
3035 	struct icnss_thermal_cdev *icnss_tcdev = NULL;
3036 
3037 	while (!list_empty(&priv->icnss_tcdev_list)) {
3038 		icnss_tcdev = list_first_entry(&priv->icnss_tcdev_list,
3039 					       struct icnss_thermal_cdev,
3040 					       tcdev_list);
3041 		thermal_cooling_device_unregister(icnss_tcdev->tcdev);
3042 		list_del(&icnss_tcdev->tcdev_list);
3043 		kfree(icnss_tcdev);
3044 	}
3045 }
3046 EXPORT_SYMBOL(icnss_thermal_cdev_unregister);
3047 
icnss_get_curr_therm_cdev_state(struct device * dev,unsigned long * thermal_state,int tcdev_id)3048 int icnss_get_curr_therm_cdev_state(struct device *dev,
3049 				    unsigned long *thermal_state,
3050 				    int tcdev_id)
3051 {
3052 	struct icnss_priv *priv = dev_get_drvdata(dev);
3053 	struct icnss_thermal_cdev *icnss_tcdev = NULL;
3054 
3055 	mutex_lock(&priv->tcdev_lock);
3056 	list_for_each_entry(icnss_tcdev, &priv->icnss_tcdev_list, tcdev_list) {
3057 		if (icnss_tcdev->tcdev_id != tcdev_id)
3058 			continue;
3059 
3060 		*thermal_state = icnss_tcdev->curr_thermal_state;
3061 		mutex_unlock(&priv->tcdev_lock);
3062 		icnss_pr_dbg("Cooling device current state: %ld, for cdev id %d",
3063 			     icnss_tcdev->curr_thermal_state, tcdev_id);
3064 		return 0;
3065 	}
3066 	mutex_unlock(&priv->tcdev_lock);
3067 	icnss_pr_dbg("Cooling device ID not found: %d", tcdev_id);
3068 	return -EINVAL;
3069 }
3070 EXPORT_SYMBOL(icnss_get_curr_therm_cdev_state);
3071 
icnss_qmi_send(struct device * dev,int type,void * cmd,int cmd_len,void * cb_ctx,int (* cb)(void * ctx,void * event,int event_len))3072 int icnss_qmi_send(struct device *dev, int type, void *cmd,
3073 		  int cmd_len, void *cb_ctx,
3074 		  int (*cb)(void *ctx, void *event, int event_len))
3075 {
3076 	struct icnss_priv *priv = icnss_get_plat_priv();
3077 	int ret;
3078 
3079 	if (!priv)
3080 		return -ENODEV;
3081 
3082 	if (!test_bit(ICNSS_WLFW_CONNECTED, &priv->state))
3083 		return -EINVAL;
3084 
3085 	priv->get_info_cb = cb;
3086 	priv->get_info_cb_ctx = cb_ctx;
3087 
3088 	ret = icnss_wlfw_get_info_send_sync(priv, type, cmd, cmd_len);
3089 	if (ret) {
3090 		priv->get_info_cb = NULL;
3091 		priv->get_info_cb_ctx = NULL;
3092 	}
3093 
3094 	return ret;
3095 }
3096 EXPORT_SYMBOL(icnss_qmi_send);
3097 
__icnss_register_driver(struct icnss_driver_ops * ops,struct module * owner,const char * mod_name)3098 int __icnss_register_driver(struct icnss_driver_ops *ops,
3099 			    struct module *owner, const char *mod_name)
3100 {
3101 	int ret = 0;
3102 	struct icnss_priv *priv = icnss_get_plat_priv();
3103 
3104 	if (!priv || !priv->pdev) {
3105 		ret = -ENODEV;
3106 		goto out;
3107 	}
3108 
3109 	icnss_pr_dbg("Registering driver, state: 0x%lx\n", priv->state);
3110 
3111 	if (priv->ops) {
3112 		icnss_pr_err("Driver already registered\n");
3113 		ret = -EEXIST;
3114 		goto out;
3115 	}
3116 
3117 	if (!ops->dev_info) {
3118 		icnss_pr_err("WLAN driver devinfo is null, Reject wlan driver loading");
3119 		return -EINVAL;
3120 	}
3121 
3122 	if (!icnss_dev_id_match(priv, ops->dev_info)) {
3123 		icnss_pr_err("WLAN driver dev name is %s, not supported by platform driver\n",
3124 			     ops->dev_info->name);
3125 		return -ENODEV;
3126 	}
3127 
3128 	if (!ops->probe || !ops->remove) {
3129 		ret = -EINVAL;
3130 		goto out;
3131 	}
3132 
3133 	ret = icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_REGISTER_DRIVER,
3134 				      0, ops);
3135 
3136 	if (ret == -EINTR)
3137 		ret = 0;
3138 
3139 out:
3140 	return ret;
3141 }
3142 EXPORT_SYMBOL(__icnss_register_driver);
3143 
icnss_unregister_driver(struct icnss_driver_ops * ops)3144 int icnss_unregister_driver(struct icnss_driver_ops *ops)
3145 {
3146 	int ret;
3147 	struct icnss_priv *priv = icnss_get_plat_priv();
3148 
3149 	if (!priv || !priv->pdev) {
3150 		ret = -ENODEV;
3151 		goto out;
3152 	}
3153 
3154 	icnss_pr_dbg("Unregistering driver, state: 0x%lx\n", priv->state);
3155 
3156 	if (!priv->ops) {
3157 		icnss_pr_err("Driver not registered\n");
3158 		ret = -ENOENT;
3159 		goto out;
3160 	}
3161 
3162 	ret = icnss_driver_event_post(priv,
3163 					 ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
3164 				      ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
3165 out:
3166 	return ret;
3167 }
3168 EXPORT_SYMBOL(icnss_unregister_driver);
3169 
3170 static struct icnss_msi_config msi_config_wcn6750 = {
3171 	.total_vectors = 28,
3172 	.total_users = 2,
3173 	.users = (struct icnss_msi_user[]) {
3174 		{ .name = "CE", .num_vectors = 10, .base_vector = 0 },
3175 		{ .name = "DP", .num_vectors = 18, .base_vector = 10 },
3176 	},
3177 };
3178 
3179 static struct icnss_msi_config msi_config_wcn6450 = {
3180 	.total_vectors = 14,
3181 	.total_users = 2,
3182 	.users = (struct icnss_msi_user[]) {
3183 		{ .name = "CE", .num_vectors = 12, .base_vector = 0 },
3184 		{ .name = "DP", .num_vectors = 2, .base_vector = 12 },
3185 	},
3186 };
3187 
icnss_get_msi_assignment(struct icnss_priv * priv)3188 static int icnss_get_msi_assignment(struct icnss_priv *priv)
3189 {
3190 	if (priv->device_id == WCN6750_DEVICE_ID)
3191 		priv->msi_config = &msi_config_wcn6750;
3192 	else
3193 		priv->msi_config = &msi_config_wcn6450;
3194 
3195 	return 0;
3196 }
3197 
icnss_get_user_msi_assignment(struct device * dev,char * user_name,int * num_vectors,u32 * user_base_data,u32 * base_vector)3198 int icnss_get_user_msi_assignment(struct device *dev, char *user_name,
3199 				 int *num_vectors, u32 *user_base_data,
3200 				 u32 *base_vector)
3201 {
3202 	struct icnss_priv *priv = dev_get_drvdata(dev);
3203 	struct icnss_msi_config *msi_config;
3204 	int idx;
3205 
3206 	if (!priv)
3207 		return -ENODEV;
3208 
3209 	msi_config = priv->msi_config;
3210 	if (!msi_config) {
3211 		icnss_pr_err("MSI is not supported.\n");
3212 		return -EINVAL;
3213 	}
3214 
3215 	for (idx = 0; idx < msi_config->total_users; idx++) {
3216 		if (strcmp(user_name, msi_config->users[idx].name) == 0) {
3217 			*num_vectors = msi_config->users[idx].num_vectors;
3218 			*user_base_data = msi_config->users[idx].base_vector
3219 				+ priv->msi_base_data;
3220 			*base_vector = msi_config->users[idx].base_vector;
3221 
3222 			icnss_pr_dbg("Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
3223 				    user_name, *num_vectors, *user_base_data,
3224 				    *base_vector);
3225 
3226 			return 0;
3227 		}
3228 	}
3229 
3230 	icnss_pr_err("Failed to find MSI assignment for %s!\n", user_name);
3231 
3232 	return -EINVAL;
3233 }
3234 EXPORT_SYMBOL(icnss_get_user_msi_assignment);
3235 
icnss_get_msi_irq(struct device * dev,unsigned int vector)3236 int icnss_get_msi_irq(struct device *dev, unsigned int vector)
3237 {
3238 	struct icnss_priv *priv = dev_get_drvdata(dev);
3239 	int irq_num;
3240 
3241 	irq_num = priv->srng_irqs[vector];
3242 	icnss_pr_dbg("Get IRQ number %d for vector index %d\n",
3243 		     irq_num, vector);
3244 
3245 	return irq_num;
3246 }
3247 EXPORT_SYMBOL(icnss_get_msi_irq);
3248 
icnss_get_msi_address(struct device * dev,u32 * msi_addr_low,u32 * msi_addr_high)3249 void icnss_get_msi_address(struct device *dev, u32 *msi_addr_low,
3250 			   u32 *msi_addr_high)
3251 {
3252 	struct icnss_priv *priv = dev_get_drvdata(dev);
3253 
3254 	*msi_addr_low = lower_32_bits(priv->msi_addr_iova);
3255 	*msi_addr_high = upper_32_bits(priv->msi_addr_iova);
3256 
3257 }
3258 EXPORT_SYMBOL(icnss_get_msi_address);
3259 
icnss_ce_request_irq(struct device * dev,unsigned int ce_id,irqreturn_t (* handler)(int,void *),unsigned long flags,const char * name,void * ctx)3260 int icnss_ce_request_irq(struct device *dev, unsigned int ce_id,
3261 	irqreturn_t (*handler)(int, void *),
3262 		unsigned long flags, const char *name, void *ctx)
3263 {
3264 	int ret = 0;
3265 	unsigned int irq;
3266 	struct ce_irq_list *irq_entry;
3267 	struct icnss_priv *priv = dev_get_drvdata(dev);
3268 
3269 	if (!priv || !priv->pdev) {
3270 		ret = -ENODEV;
3271 		goto out;
3272 	}
3273 
3274 	icnss_pr_vdbg("CE request IRQ: %d, state: 0x%lx\n", ce_id, priv->state);
3275 
3276 	if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS) {
3277 		icnss_pr_err("Invalid CE ID, ce_id: %d\n", ce_id);
3278 		ret = -EINVAL;
3279 		goto out;
3280 	}
3281 	irq = priv->ce_irqs[ce_id];
3282 	irq_entry = &priv->ce_irq_list[ce_id];
3283 
3284 	if (irq_entry->handler || irq_entry->irq) {
3285 		icnss_pr_err("IRQ already requested: %d, ce_id: %d\n",
3286 			     irq, ce_id);
3287 		ret = -EEXIST;
3288 		goto out;
3289 	}
3290 
3291 	ret = request_irq(irq, handler, flags, name, ctx);
3292 	if (ret) {
3293 		icnss_pr_err("IRQ request failed: %d, ce_id: %d, ret: %d\n",
3294 			     irq, ce_id, ret);
3295 		goto out;
3296 	}
3297 	irq_entry->irq = irq;
3298 	irq_entry->handler = handler;
3299 
3300 	icnss_pr_vdbg("IRQ requested: %d, ce_id: %d\n", irq, ce_id);
3301 
3302 	penv->stats.ce_irqs[ce_id].request++;
3303 out:
3304 	return ret;
3305 }
3306 EXPORT_SYMBOL(icnss_ce_request_irq);
3307 
icnss_ce_free_irq(struct device * dev,unsigned int ce_id,void * ctx)3308 int icnss_ce_free_irq(struct device *dev, unsigned int ce_id, void *ctx)
3309 {
3310 	int ret = 0;
3311 	unsigned int irq;
3312 	struct ce_irq_list *irq_entry;
3313 
3314 	if (!penv || !penv->pdev || !dev) {
3315 		ret = -ENODEV;
3316 		goto out;
3317 	}
3318 
3319 	icnss_pr_vdbg("CE free IRQ: %d, state: 0x%lx\n", ce_id, penv->state);
3320 
3321 	if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS) {
3322 		icnss_pr_err("Invalid CE ID to free, ce_id: %d\n", ce_id);
3323 		ret = -EINVAL;
3324 		goto out;
3325 	}
3326 
3327 	irq = penv->ce_irqs[ce_id];
3328 	irq_entry = &penv->ce_irq_list[ce_id];
3329 	if (!irq_entry->handler || !irq_entry->irq) {
3330 		icnss_pr_err("IRQ not requested: %d, ce_id: %d\n", irq, ce_id);
3331 		ret = -EEXIST;
3332 		goto out;
3333 	}
3334 	free_irq(irq, ctx);
3335 	irq_entry->irq = 0;
3336 	irq_entry->handler = NULL;
3337 
3338 	penv->stats.ce_irqs[ce_id].free++;
3339 out:
3340 	return ret;
3341 }
3342 EXPORT_SYMBOL(icnss_ce_free_irq);
3343 
icnss_enable_irq(struct device * dev,unsigned int ce_id)3344 void icnss_enable_irq(struct device *dev, unsigned int ce_id)
3345 {
3346 	unsigned int irq;
3347 
3348 	if (!penv || !penv->pdev || !dev) {
3349 		icnss_pr_err("Platform driver not initialized\n");
3350 		return;
3351 	}
3352 
3353 	icnss_pr_vdbg("Enable IRQ: ce_id: %d, state: 0x%lx\n", ce_id,
3354 		     penv->state);
3355 
3356 	if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS) {
3357 		icnss_pr_err("Invalid CE ID to enable IRQ, ce_id: %d\n", ce_id);
3358 		return;
3359 	}
3360 
3361 	penv->stats.ce_irqs[ce_id].enable++;
3362 
3363 	irq = penv->ce_irqs[ce_id];
3364 	enable_irq(irq);
3365 }
3366 EXPORT_SYMBOL(icnss_enable_irq);
3367 
icnss_disable_irq(struct device * dev,unsigned int ce_id)3368 void icnss_disable_irq(struct device *dev, unsigned int ce_id)
3369 {
3370 	unsigned int irq;
3371 
3372 	if (!penv || !penv->pdev || !dev) {
3373 		icnss_pr_err("Platform driver not initialized\n");
3374 		return;
3375 	}
3376 
3377 	icnss_pr_vdbg("Disable IRQ: ce_id: %d, state: 0x%lx\n", ce_id,
3378 		     penv->state);
3379 
3380 	if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS) {
3381 		icnss_pr_err("Invalid CE ID to disable IRQ, ce_id: %d\n",
3382 			     ce_id);
3383 		return;
3384 	}
3385 
3386 	irq = penv->ce_irqs[ce_id];
3387 	disable_irq(irq);
3388 
3389 	penv->stats.ce_irqs[ce_id].disable++;
3390 }
3391 EXPORT_SYMBOL(icnss_disable_irq);
3392 
icnss_get_soc_info(struct device * dev,struct icnss_soc_info * info)3393 int icnss_get_soc_info(struct device *dev, struct icnss_soc_info *info)
3394 {
3395 	char *fw_build_timestamp = NULL;
3396 	struct icnss_priv *priv = dev_get_drvdata(dev);
3397 
3398 	if (!priv) {
3399 		icnss_pr_err("Platform driver not initialized\n");
3400 		return -EINVAL;
3401 	}
3402 
3403 	info->v_addr = priv->mem_base_va;
3404 	info->p_addr = priv->mem_base_pa;
3405 	info->chip_id = priv->chip_info.chip_id;
3406 	info->chip_family = priv->chip_info.chip_family;
3407 	info->board_id = priv->board_id;
3408 	info->soc_id = priv->soc_id;
3409 	info->fw_version = priv->fw_version_info.fw_version;
3410 	fw_build_timestamp = priv->fw_version_info.fw_build_timestamp;
3411 	fw_build_timestamp[WLFW_MAX_TIMESTAMP_LEN] = '\0';
3412 	strlcpy(info->fw_build_timestamp,
3413 		priv->fw_version_info.fw_build_timestamp,
3414 		WLFW_MAX_TIMESTAMP_LEN + 1);
3415 	strlcpy(info->fw_build_id, priv->fw_build_id,
3416 	        ICNSS_WLFW_MAX_BUILD_ID_LEN + 1);
3417 	info->rd_card_chain_cap = priv->rd_card_chain_cap;
3418 	info->phy_he_channel_width_cap = priv->phy_he_channel_width_cap;
3419 	info->phy_qam_cap = priv->phy_qam_cap;
3420 	memcpy(&info->dev_mem_info, &priv->dev_mem_info,
3421 	       sizeof(info->dev_mem_info));
3422 
3423 	return 0;
3424 }
3425 EXPORT_SYMBOL(icnss_get_soc_info);
3426 
icnss_get_mhi_state(struct device * dev)3427 int icnss_get_mhi_state(struct device *dev)
3428 {
3429 	struct icnss_priv *priv = dev_get_drvdata(dev);
3430 
3431 	if (!priv) {
3432 		icnss_pr_err("Platform driver not initialized\n");
3433 		return -EINVAL;
3434 	}
3435 
3436 	if (!priv->mhi_state_info_va)
3437 		return -ENOMEM;
3438 
3439 	return ioread32(priv->mhi_state_info_va);
3440 }
3441 EXPORT_SYMBOL(icnss_get_mhi_state);
3442 
icnss_set_fw_log_mode(struct device * dev,uint8_t fw_log_mode)3443 int icnss_set_fw_log_mode(struct device *dev, uint8_t fw_log_mode)
3444 {
3445 	int ret;
3446 	struct icnss_priv *priv;
3447 
3448 	if (!dev)
3449 		return -ENODEV;
3450 
3451 	priv = dev_get_drvdata(dev);
3452 
3453 	if (!priv) {
3454 		icnss_pr_err("Platform driver not initialized\n");
3455 		return -EINVAL;
3456 	}
3457 
3458 	if (test_bit(ICNSS_FW_DOWN, &penv->state) ||
3459 	    !test_bit(ICNSS_FW_READY, &penv->state)) {
3460 		icnss_pr_err("FW down, ignoring fw_log_mode state: 0x%lx\n",
3461 			     priv->state);
3462 		return -EINVAL;
3463 	}
3464 
3465 	icnss_pr_dbg("FW log mode: %u\n", fw_log_mode);
3466 
3467 	ret = wlfw_ini_send_sync_msg(priv, fw_log_mode);
3468 	if (ret)
3469 		icnss_pr_err("Fail to send ini, ret = %d, fw_log_mode: %u\n",
3470 			     ret, fw_log_mode);
3471 	return ret;
3472 }
3473 EXPORT_SYMBOL(icnss_set_fw_log_mode);
3474 
icnss_force_wake_request(struct device * dev)3475 int icnss_force_wake_request(struct device *dev)
3476 {
3477 	struct icnss_priv *priv;
3478 
3479 	if (!dev)
3480 		return -ENODEV;
3481 
3482 	priv = dev_get_drvdata(dev);
3483 
3484 	if (!priv) {
3485 		icnss_pr_err("Platform driver not initialized\n");
3486 		return -EINVAL;
3487 	}
3488 
3489 	if (test_bit(ICNSS_FW_DOWN, &priv->state) ||
3490 	    !test_bit(ICNSS_FW_READY, &priv->state)) {
3491 		icnss_pr_soc_wake("FW down, ignoring SOC Wake request state: 0x%lx\n",
3492 				  priv->state);
3493 		return -EINVAL;
3494 	}
3495 
3496 	if (atomic_inc_not_zero(&priv->soc_wake_ref_count)) {
3497 		icnss_pr_soc_wake("SOC already awake, Ref count: %d",
3498 				  atomic_read(&priv->soc_wake_ref_count));
3499 		return 0;
3500 	}
3501 
3502 	icnss_pr_soc_wake("Calling SOC Wake request");
3503 
3504 	icnss_soc_wake_event_post(priv, ICNSS_SOC_WAKE_REQUEST_EVENT,
3505 				  0, NULL);
3506 
3507 	return 0;
3508 }
3509 EXPORT_SYMBOL(icnss_force_wake_request);
3510 
icnss_force_wake_release(struct device * dev)3511 int icnss_force_wake_release(struct device *dev)
3512 {
3513 	struct icnss_priv *priv;
3514 
3515 	if (!dev)
3516 		return -ENODEV;
3517 
3518 	priv = dev_get_drvdata(dev);
3519 
3520 	if (!priv) {
3521 		icnss_pr_err("Platform driver not initialized\n");
3522 		return -EINVAL;
3523 	}
3524 
3525 	if (test_bit(ICNSS_FW_DOWN, &priv->state) ||
3526 	    !test_bit(ICNSS_FW_READY, &priv->state)) {
3527 		icnss_pr_soc_wake("FW down, ignoring SOC Wake release state: 0x%lx\n",
3528 				  priv->state);
3529 		return -EINVAL;
3530 	}
3531 
3532 	icnss_pr_soc_wake("Calling SOC Wake response");
3533 
3534 	if (atomic_read(&priv->soc_wake_ref_count) &&
3535 	    icnss_atomic_dec_if_greater_one(&priv->soc_wake_ref_count)) {
3536 		icnss_pr_soc_wake("SOC previous release pending, Ref count: %d",
3537 				  atomic_read(&priv->soc_wake_ref_count));
3538 		return 0;
3539 	}
3540 
3541 	icnss_soc_wake_event_post(priv, ICNSS_SOC_WAKE_RELEASE_EVENT,
3542 				  0, NULL);
3543 
3544 	return 0;
3545 }
3546 EXPORT_SYMBOL(icnss_force_wake_release);
3547 
icnss_is_device_awake(struct device * dev)3548 int icnss_is_device_awake(struct device *dev)
3549 {
3550 	struct icnss_priv *priv = dev_get_drvdata(dev);
3551 
3552 	if (!priv) {
3553 		icnss_pr_err("Platform driver not initialized\n");
3554 		return -EINVAL;
3555 	}
3556 
3557 	return atomic_read(&priv->soc_wake_ref_count);
3558 }
3559 EXPORT_SYMBOL(icnss_is_device_awake);
3560 
icnss_is_pci_ep_awake(struct device * dev)3561 int icnss_is_pci_ep_awake(struct device *dev)
3562 {
3563 	struct icnss_priv *priv = dev_get_drvdata(dev);
3564 
3565 	if (!priv) {
3566 		icnss_pr_err("Platform driver not initialized\n");
3567 		return -EINVAL;
3568 	}
3569 
3570 	if (!priv->mhi_state_info_va)
3571 		return -ENOMEM;
3572 
3573 	return ioread32(priv->mhi_state_info_va + ICNSS_PCI_EP_WAKE_OFFSET);
3574 }
3575 EXPORT_SYMBOL(icnss_is_pci_ep_awake);
3576 
icnss_athdiag_read(struct device * dev,uint32_t offset,uint32_t mem_type,uint32_t data_len,uint8_t * output)3577 int icnss_athdiag_read(struct device *dev, uint32_t offset,
3578 		       uint32_t mem_type, uint32_t data_len,
3579 		       uint8_t *output)
3580 {
3581 	int ret = 0;
3582 	struct icnss_priv *priv = dev_get_drvdata(dev);
3583 
3584 	if (priv->magic != ICNSS_MAGIC) {
3585 		icnss_pr_err("Invalid drvdata for diag read: dev %pK, data %pK, magic 0x%x\n",
3586 			     dev, priv, priv->magic);
3587 		return -EINVAL;
3588 	}
3589 
3590 	if (!output || data_len == 0
3591 	    || data_len > WLFW_MAX_DATA_SIZE) {
3592 		icnss_pr_err("Invalid parameters for diag read: output %pK, data_len %u\n",
3593 			     output, data_len);
3594 		ret = -EINVAL;
3595 		goto out;
3596 	}
3597 
3598 	if (!test_bit(ICNSS_FW_READY, &priv->state) ||
3599 	    !test_bit(ICNSS_POWER_ON, &priv->state)) {
3600 		icnss_pr_err("Invalid state for diag read: 0x%lx\n",
3601 			     priv->state);
3602 		ret = -EINVAL;
3603 		goto out;
3604 	}
3605 
3606 	ret = wlfw_athdiag_read_send_sync_msg(priv, offset, mem_type,
3607 					      data_len, output);
3608 out:
3609 	return ret;
3610 }
3611 EXPORT_SYMBOL(icnss_athdiag_read);
3612 
icnss_athdiag_write(struct device * dev,uint32_t offset,uint32_t mem_type,uint32_t data_len,uint8_t * input)3613 int icnss_athdiag_write(struct device *dev, uint32_t offset,
3614 			uint32_t mem_type, uint32_t data_len,
3615 			uint8_t *input)
3616 {
3617 	int ret = 0;
3618 	struct icnss_priv *priv = dev_get_drvdata(dev);
3619 
3620 	if (priv->magic != ICNSS_MAGIC) {
3621 		icnss_pr_err("Invalid drvdata for diag write: dev %pK, data %pK, magic 0x%x\n",
3622 			     dev, priv, priv->magic);
3623 		return -EINVAL;
3624 	}
3625 
3626 	if (!input || data_len == 0
3627 	    || data_len > WLFW_MAX_DATA_SIZE) {
3628 		icnss_pr_err("Invalid parameters for diag write: input %pK, data_len %u\n",
3629 			     input, data_len);
3630 		ret = -EINVAL;
3631 		goto out;
3632 	}
3633 
3634 	if (!test_bit(ICNSS_FW_READY, &priv->state) ||
3635 	    !test_bit(ICNSS_POWER_ON, &priv->state)) {
3636 		icnss_pr_err("Invalid state for diag write: 0x%lx\n",
3637 			     priv->state);
3638 		ret = -EINVAL;
3639 		goto out;
3640 	}
3641 
3642 	ret = wlfw_athdiag_write_send_sync_msg(priv, offset, mem_type,
3643 					       data_len, input);
3644 out:
3645 	return ret;
3646 }
3647 EXPORT_SYMBOL(icnss_athdiag_write);
3648 
icnss_wlan_enable(struct device * dev,struct icnss_wlan_enable_cfg * config,enum icnss_driver_mode mode,const char * host_version)3649 int icnss_wlan_enable(struct device *dev, struct icnss_wlan_enable_cfg *config,
3650 		      enum icnss_driver_mode mode,
3651 		      const char *host_version)
3652 {
3653 	struct icnss_priv *priv = dev_get_drvdata(dev);
3654 	int temp = 0, ret = 0;
3655 
3656 	if (test_bit(ICNSS_FW_DOWN, &priv->state) ||
3657 	    !test_bit(ICNSS_FW_READY, &priv->state)) {
3658 		icnss_pr_err("FW down, ignoring wlan_enable state: 0x%lx\n",
3659 			     priv->state);
3660 		return -EINVAL;
3661 	}
3662 
3663 	if (test_bit(ICNSS_MODE_ON, &priv->state)) {
3664 		icnss_pr_err("Already Mode on, ignoring wlan_enable state: 0x%lx\n",
3665 			     priv->state);
3666 		return -EINVAL;
3667 	}
3668 
3669 	if (priv->wpss_supported &&
3670 	    !priv->dms.nv_mac_not_prov && !priv->dms.mac_valid)
3671 		icnss_setup_dms_mac(priv);
3672 
3673 	if (priv->device_id == WCN6750_DEVICE_ID) {
3674 		if (!icnss_get_temperature(priv, &temp)) {
3675 			icnss_pr_dbg("Temperature: %d\n", temp);
3676 			if (temp < WLAN_EN_TEMP_THRESHOLD)
3677 				icnss_set_wlan_en_delay(priv);
3678 		}
3679 	}
3680 
3681 	if (priv->device_id == WCN6450_DEVICE_ID)
3682 		icnss_hw_power_off(priv);
3683 
3684 	ret = icnss_send_wlan_enable_to_fw(priv, config, mode, host_version);
3685 
3686 	if (priv->device_id == WCN6450_DEVICE_ID)
3687 		icnss_hw_power_on(priv);
3688 
3689 	return ret;
3690 }
3691 EXPORT_SYMBOL(icnss_wlan_enable);
3692 
icnss_wlan_disable(struct device * dev,enum icnss_driver_mode mode)3693 int icnss_wlan_disable(struct device *dev, enum icnss_driver_mode mode)
3694 {
3695 	struct icnss_priv *priv = dev_get_drvdata(dev);
3696 
3697 	if (test_bit(ICNSS_FW_DOWN, &priv->state)) {
3698 		icnss_pr_dbg("FW down, ignoring wlan_disable state: 0x%lx\n",
3699 			     priv->state);
3700 		return 0;
3701 	}
3702 
3703 	return icnss_send_wlan_disable_to_fw(priv);
3704 }
3705 EXPORT_SYMBOL(icnss_wlan_disable);
3706 
icnss_is_qmi_disable(struct device * dev)3707 bool icnss_is_qmi_disable(struct device *dev)
3708 {
3709 	return test_bit(SKIP_QMI, &penv->ctrl_params.quirks) ? true : false;
3710 }
3711 EXPORT_SYMBOL(icnss_is_qmi_disable);
3712 
icnss_get_ce_id(struct device * dev,int irq)3713 int icnss_get_ce_id(struct device *dev, int irq)
3714 {
3715 	int i;
3716 
3717 	if (!penv || !penv->pdev || !dev)
3718 		return -ENODEV;
3719 
3720 	for (i = 0; i < ICNSS_MAX_IRQ_REGISTRATIONS; i++) {
3721 		if (penv->ce_irqs[i] == irq)
3722 			return i;
3723 	}
3724 
3725 	icnss_pr_err("No matching CE id for irq %d\n", irq);
3726 
3727 	return -EINVAL;
3728 }
3729 EXPORT_SYMBOL(icnss_get_ce_id);
3730 
icnss_get_irq(struct device * dev,int ce_id)3731 int icnss_get_irq(struct device *dev, int ce_id)
3732 {
3733 	int irq;
3734 
3735 	if (!penv || !penv->pdev || !dev)
3736 		return -ENODEV;
3737 
3738 	if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS)
3739 		return -EINVAL;
3740 
3741 	irq = penv->ce_irqs[ce_id];
3742 
3743 	return irq;
3744 }
3745 EXPORT_SYMBOL(icnss_get_irq);
3746 
icnss_smmu_get_domain(struct device * dev)3747 struct iommu_domain *icnss_smmu_get_domain(struct device *dev)
3748 {
3749 	struct icnss_priv *priv = dev_get_drvdata(dev);
3750 
3751 	if (!priv) {
3752 		icnss_pr_err("Invalid drvdata: dev %pK\n", dev);
3753 		return NULL;
3754 	}
3755 	return priv->iommu_domain;
3756 }
3757 EXPORT_SYMBOL(icnss_smmu_get_domain);
3758 
3759 #if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0))
icnss_iommu_map(struct iommu_domain * domain,unsigned long iova,phys_addr_t paddr,size_t size,int prot)3760 int icnss_iommu_map(struct iommu_domain *domain,
3761 				   unsigned long iova, phys_addr_t paddr, size_t size, int prot)
3762 {
3763 		return iommu_map(domain, iova, paddr, size, prot);
3764 }
3765 #else
icnss_iommu_map(struct iommu_domain * domain,unsigned long iova,phys_addr_t paddr,size_t size,int prot)3766 int icnss_iommu_map(struct iommu_domain *domain,
3767 				   unsigned long iova, phys_addr_t paddr, size_t size, int prot)
3768 {
3769 		return iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL);
3770 }
3771 #endif
3772 
icnss_smmu_map(struct device * dev,phys_addr_t paddr,uint32_t * iova_addr,size_t size)3773 int icnss_smmu_map(struct device *dev,
3774 		   phys_addr_t paddr, uint32_t *iova_addr, size_t size)
3775 {
3776 	struct icnss_priv *priv = dev_get_drvdata(dev);
3777 	int flag = IOMMU_READ | IOMMU_WRITE;
3778 	bool dma_coherent = false;
3779 	unsigned long iova;
3780 	int prop_len = 0;
3781 	size_t len;
3782 	int ret = 0;
3783 
3784 	if (!priv) {
3785 		icnss_pr_err("Invalid drvdata: dev %pK, data %pK\n",
3786 			     dev, priv);
3787 		return -EINVAL;
3788 	}
3789 
3790 	if (!iova_addr) {
3791 		icnss_pr_err("iova_addr is NULL, paddr %pa, size %zu\n",
3792 			     &paddr, size);
3793 		return -EINVAL;
3794 	}
3795 
3796 	len = roundup(size + paddr - rounddown(paddr, PAGE_SIZE), PAGE_SIZE);
3797 	iova = roundup(priv->smmu_iova_ipa_current, PAGE_SIZE);
3798 
3799 	if (of_get_property(dev->of_node, "qcom,iommu-geometry", &prop_len) &&
3800 	    iova >= priv->smmu_iova_ipa_start + priv->smmu_iova_ipa_len) {
3801 		icnss_pr_err("No IOVA space to map, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
3802 			     iova,
3803 			     &priv->smmu_iova_ipa_start,
3804 			     priv->smmu_iova_ipa_len);
3805 		return -ENOMEM;
3806 	}
3807 
3808 	dma_coherent = of_property_read_bool(dev->of_node, "dma-coherent");
3809 	icnss_pr_dbg("dma-coherent is %s\n",
3810 		     dma_coherent ? "enabled" : "disabled");
3811 	if (dma_coherent)
3812 		flag |= IOMMU_CACHE;
3813 
3814 	icnss_pr_dbg("IOMMU Map: iova %lx, len %zu\n", iova, len);
3815 
3816 	ret = icnss_iommu_map(priv->iommu_domain, iova,
3817 			rounddown(paddr, PAGE_SIZE), len,
3818 			flag);
3819 	if (ret) {
3820 		icnss_pr_err("PA to IOVA mapping failed, ret %d\n", ret);
3821 		return ret;
3822 	}
3823 
3824 	priv->smmu_iova_ipa_current = iova + len;
3825 	*iova_addr = (uint32_t)(iova + paddr - rounddown(paddr, PAGE_SIZE));
3826 
3827 	icnss_pr_dbg("IOVA addr mapped to physical addr %lx\n", *iova_addr);
3828 	return 0;
3829 }
3830 EXPORT_SYMBOL(icnss_smmu_map);
3831 
icnss_smmu_unmap(struct device * dev,uint32_t iova_addr,size_t size)3832 int icnss_smmu_unmap(struct device *dev,
3833 		     uint32_t iova_addr, size_t size)
3834 {
3835 	struct icnss_priv *priv = dev_get_drvdata(dev);
3836 	unsigned long iova;
3837 	size_t len, unmapped_len;
3838 
3839 	if (!priv) {
3840 		icnss_pr_err("Invalid drvdata: dev %pK, data %pK\n",
3841 			     dev, priv);
3842 		return -EINVAL;
3843 	}
3844 
3845 	if (!iova_addr) {
3846 		icnss_pr_err("iova_addr is NULL, size %zu\n",
3847 			     size);
3848 		return -EINVAL;
3849 	}
3850 
3851 	len = roundup(size + iova_addr - rounddown(iova_addr, PAGE_SIZE),
3852 		      PAGE_SIZE);
3853 	iova = rounddown(iova_addr, PAGE_SIZE);
3854 
3855 	if (iova >= priv->smmu_iova_ipa_start + priv->smmu_iova_ipa_len) {
3856 		icnss_pr_err("Out of IOVA space during unmap, iova %lx, smmu_iova_ipa_start %pad, smmu_iova_ipa_len %zu\n",
3857 			     iova,
3858 			     &priv->smmu_iova_ipa_start,
3859 			     priv->smmu_iova_ipa_len);
3860 		return -ENOMEM;
3861 	}
3862 
3863 	icnss_pr_dbg("IOMMU Unmap: iova %lx, len %zu\n",
3864 		     iova, len);
3865 
3866 	unmapped_len = iommu_unmap(priv->iommu_domain, iova, len);
3867 	if (unmapped_len != len) {
3868 		icnss_pr_err("Failed to unmap, %zu\n", unmapped_len);
3869 		return -EINVAL;
3870 	}
3871 
3872 	priv->smmu_iova_ipa_current = iova;
3873 	return 0;
3874 }
3875 EXPORT_SYMBOL(icnss_smmu_unmap);
3876 
icnss_socinfo_get_serial_number(struct device * dev)3877 unsigned int icnss_socinfo_get_serial_number(struct device *dev)
3878 {
3879 	return socinfo_get_serial_number();
3880 }
3881 EXPORT_SYMBOL(icnss_socinfo_get_serial_number);
3882 
icnss_trigger_recovery(struct device * dev)3883 int icnss_trigger_recovery(struct device *dev)
3884 {
3885 	int ret = 0;
3886 	struct icnss_priv *priv = dev_get_drvdata(dev);
3887 
3888 	if (priv->magic != ICNSS_MAGIC) {
3889 		icnss_pr_err("Invalid drvdata: magic 0x%x\n", priv->magic);
3890 		ret = -EINVAL;
3891 		goto out;
3892 	}
3893 
3894 	if (test_bit(ICNSS_PD_RESTART, &priv->state)) {
3895 		icnss_pr_err("PD recovery already in progress: state: 0x%lx\n",
3896 			     priv->state);
3897 		ret = -EPERM;
3898 		goto out;
3899 	}
3900 
3901 	if (priv->wpss_supported) {
3902 		icnss_pr_vdbg("Initiate Root PD restart");
3903 		ret = icnss_send_smp2p(priv, ICNSS_TRIGGER_SSR,
3904 				       ICNSS_SMP2P_OUT_POWER_SAVE);
3905 		if (!ret)
3906 			set_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
3907 		return ret;
3908 	}
3909 
3910 	if (!test_bit(ICNSS_PDR_REGISTERED, &priv->state)) {
3911 		icnss_pr_err("PD restart not enabled to trigger recovery: state: 0x%lx\n",
3912 			     priv->state);
3913 		ret = -EOPNOTSUPP;
3914 		goto out;
3915 	}
3916 
3917 	icnss_pr_warn("Initiate PD restart at WLAN FW, state: 0x%lx\n",
3918 		      priv->state);
3919 
3920 	ret = pdr_restart_pd(priv->pdr_handle, priv->pdr_service);
3921 
3922 	if (!ret)
3923 		set_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state);
3924 
3925 out:
3926 	return ret;
3927 }
3928 EXPORT_SYMBOL(icnss_trigger_recovery);
3929 
icnss_idle_shutdown(struct device * dev)3930 int icnss_idle_shutdown(struct device *dev)
3931 {
3932 	struct icnss_priv *priv = dev_get_drvdata(dev);
3933 
3934 	if (!priv) {
3935 		icnss_pr_err("Invalid drvdata: dev %pK", dev);
3936 		return -EINVAL;
3937 	}
3938 
3939 	if (priv->is_ssr || test_bit(ICNSS_PDR, &priv->state) ||
3940 	    test_bit(ICNSS_REJUVENATE, &priv->state)) {
3941 		icnss_pr_err("SSR/PDR is already in-progress during idle shutdown\n");
3942 		return -EBUSY;
3943 	}
3944 
3945 	return icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
3946 					ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
3947 }
3948 EXPORT_SYMBOL(icnss_idle_shutdown);
3949 
icnss_idle_restart(struct device * dev)3950 int icnss_idle_restart(struct device *dev)
3951 {
3952 	struct icnss_priv *priv = dev_get_drvdata(dev);
3953 
3954 	if (!priv) {
3955 		icnss_pr_err("Invalid drvdata: dev %pK", dev);
3956 		return -EINVAL;
3957 	}
3958 
3959 	if (priv->is_ssr || test_bit(ICNSS_PDR, &priv->state) ||
3960 	    test_bit(ICNSS_REJUVENATE, &priv->state)) {
3961 		icnss_pr_err("SSR/PDR is already in-progress during idle restart\n");
3962 		return -EBUSY;
3963 	}
3964 
3965 	return icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_IDLE_RESTART,
3966 					ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
3967 }
3968 EXPORT_SYMBOL(icnss_idle_restart);
3969 
icnss_exit_power_save(struct device * dev)3970 int icnss_exit_power_save(struct device *dev)
3971 {
3972 	struct icnss_priv *priv = dev_get_drvdata(dev);
3973 
3974 	icnss_pr_vdbg("Calling Exit Power Save\n");
3975 
3976 	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
3977 	    !test_bit(ICNSS_MODE_ON, &priv->state))
3978 		return 0;
3979 
3980 	return icnss_send_smp2p(priv, ICNSS_POWER_SAVE_EXIT,
3981 				ICNSS_SMP2P_OUT_POWER_SAVE);
3982 }
3983 EXPORT_SYMBOL(icnss_exit_power_save);
3984 
icnss_prevent_l1(struct device * dev)3985 int icnss_prevent_l1(struct device *dev)
3986 {
3987 	struct icnss_priv *priv = dev_get_drvdata(dev);
3988 
3989 	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
3990 	    !test_bit(ICNSS_MODE_ON, &priv->state))
3991 		return 0;
3992 
3993 	return icnss_send_smp2p(priv, ICNSS_PCI_EP_POWER_SAVE_EXIT,
3994 				ICNSS_SMP2P_OUT_EP_POWER_SAVE);
3995 }
3996 EXPORT_SYMBOL(icnss_prevent_l1);
3997 
icnss_allow_l1(struct device * dev)3998 void icnss_allow_l1(struct device *dev)
3999 {
4000 	struct icnss_priv *priv = dev_get_drvdata(dev);
4001 
4002 	if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
4003 	    !test_bit(ICNSS_MODE_ON, &priv->state))
4004 		return;
4005 
4006 	icnss_send_smp2p(priv, ICNSS_PCI_EP_POWER_SAVE_ENTER,
4007 			 ICNSS_SMP2P_OUT_EP_POWER_SAVE);
4008 }
4009 EXPORT_SYMBOL(icnss_allow_l1);
4010 
icnss_allow_recursive_recovery(struct device * dev)4011 void icnss_allow_recursive_recovery(struct device *dev)
4012 {
4013 	struct icnss_priv *priv = dev_get_drvdata(dev);
4014 
4015 	priv->allow_recursive_recovery = true;
4016 
4017 	icnss_pr_info("Recursive recovery allowed for WLAN\n");
4018 }
4019 
icnss_disallow_recursive_recovery(struct device * dev)4020 void icnss_disallow_recursive_recovery(struct device *dev)
4021 {
4022 	struct icnss_priv *priv = dev_get_drvdata(dev);
4023 
4024 	priv->allow_recursive_recovery = false;
4025 
4026 	icnss_pr_info("Recursive recovery disallowed for WLAN\n");
4027 }
4028 
icnss_create_shutdown_sysfs(struct icnss_priv * priv)4029 static int icnss_create_shutdown_sysfs(struct icnss_priv *priv)
4030 {
4031 	struct kobject *icnss_kobject;
4032 	int ret = 0;
4033 
4034 	atomic_set(&priv->is_shutdown, false);
4035 
4036 	icnss_kobject = kobject_create_and_add("shutdown_wlan", kernel_kobj);
4037 	if (!icnss_kobject) {
4038 		icnss_pr_err("Unable to create shutdown_wlan kernel object");
4039 		return -EINVAL;
4040 	}
4041 
4042 	priv->icnss_kobject = icnss_kobject;
4043 
4044 	ret = sysfs_create_file(icnss_kobject, &icnss_sysfs_attribute.attr);
4045 	if (ret) {
4046 		icnss_pr_err("Unable to create icnss sysfs file err:%d", ret);
4047 		return ret;
4048 	}
4049 
4050 	return ret;
4051 }
4052 
icnss_destroy_shutdown_sysfs(struct icnss_priv * priv)4053 static void icnss_destroy_shutdown_sysfs(struct icnss_priv *priv)
4054 {
4055 	struct kobject *icnss_kobject;
4056 
4057 	icnss_kobject = priv->icnss_kobject;
4058 	if (icnss_kobject)
4059 		kobject_put(icnss_kobject);
4060 }
4061 
qdss_tr_start_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)4062 static ssize_t qdss_tr_start_store(struct device *dev,
4063 				   struct device_attribute *attr,
4064 				   const char *buf, size_t count)
4065 {
4066 	struct icnss_priv *priv = dev_get_drvdata(dev);
4067 
4068 	wlfw_qdss_trace_start(priv);
4069 	icnss_pr_dbg("Received QDSS start command\n");
4070 	return count;
4071 }
4072 
qdss_tr_stop_store(struct device * dev,struct device_attribute * attr,const char * user_buf,size_t count)4073 static ssize_t qdss_tr_stop_store(struct device *dev,
4074 				  struct device_attribute *attr,
4075 				  const char *user_buf, size_t count)
4076 {
4077 	struct icnss_priv *priv = dev_get_drvdata(dev);
4078 	u32 option = 0;
4079 
4080 	if (sscanf(user_buf, "%du", &option) != 1)
4081 		return -EINVAL;
4082 
4083 	wlfw_qdss_trace_stop(priv, option);
4084 	icnss_pr_dbg("Received QDSS stop command\n");
4085 	return count;
4086 }
4087 
qdss_conf_download_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)4088 static ssize_t qdss_conf_download_store(struct device *dev,
4089 					struct device_attribute *attr,
4090 					const char *buf, size_t count)
4091 {
4092 	struct icnss_priv *priv = dev_get_drvdata(dev);
4093 
4094 	icnss_wlfw_qdss_dnld_send_sync(priv);
4095 	icnss_pr_dbg("Received QDSS download config command\n");
4096 	return count;
4097 }
4098 
hw_trc_override_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)4099 static ssize_t hw_trc_override_store(struct device *dev,
4100 				     struct device_attribute *attr,
4101 				     const char *buf, size_t count)
4102 {
4103 	struct icnss_priv *priv = dev_get_drvdata(dev);
4104 	int tmp = 0;
4105 
4106 	if (sscanf(buf, "%du", &tmp) != 1)
4107 		return -EINVAL;
4108 
4109 	priv->hw_trc_override = tmp;
4110 	icnss_pr_dbg("Received QDSS hw_trc_override indication\n");
4111 	return count;
4112 }
4113 
icnss_wpss_load(struct work_struct * wpss_load_work)4114 static void icnss_wpss_load(struct work_struct *wpss_load_work)
4115 {
4116 	struct icnss_priv *priv = icnss_get_plat_priv();
4117 	phandle rproc_phandle;
4118 	int ret;
4119 
4120 	if (of_property_read_u32(priv->pdev->dev.of_node, "qcom,rproc-handle",
4121 				 &rproc_phandle)) {
4122 		icnss_pr_err("error reading rproc phandle\n");
4123 		return;
4124 	}
4125 
4126 	priv->rproc = rproc_get_by_phandle(rproc_phandle);
4127 	if (IS_ERR_OR_NULL(priv->rproc)) {
4128 		icnss_pr_err("rproc not found");
4129 		return;
4130 	}
4131 
4132 	ret = rproc_boot(priv->rproc);
4133 	if (ret) {
4134 		icnss_pr_err("Failed to boot wpss rproc, ret: %d", ret);
4135 		rproc_put(priv->rproc);
4136 	}
4137 }
4138 
wpss_boot_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)4139 static ssize_t wpss_boot_store(struct device *dev,
4140 			       struct device_attribute *attr,
4141 			       const char *buf, size_t count)
4142 {
4143 	struct icnss_priv *priv = dev_get_drvdata(dev);
4144 	int wpss_rproc = 0;
4145 
4146 	if (!priv->wpss_supported && !priv->rproc_fw_download)
4147 		return count;
4148 
4149 	if (sscanf(buf, "%du", &wpss_rproc) != 1) {
4150 		icnss_pr_err("Failed to read wpss rproc info");
4151 		return -EINVAL;
4152 	}
4153 
4154 	icnss_pr_dbg("WPSS Remote Processor: %s", wpss_rproc ? "GET" : "PUT");
4155 
4156 	if (wpss_rproc == 1)
4157 		schedule_work(&wpss_loader);
4158 	else if (wpss_rproc == 0)
4159 		icnss_wpss_unload(priv);
4160 
4161 	return count;
4162 }
4163 
wlan_en_delay_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)4164 static ssize_t wlan_en_delay_store(struct device *dev,
4165 			       struct device_attribute *attr,
4166 			       const char *buf, size_t count)
4167 {
4168 	struct icnss_priv *priv = dev_get_drvdata(dev);
4169 	uint32_t wlan_en_delay  = 0;
4170 
4171 	if (priv->device_id == ADRASTEA_DEVICE_ID)
4172 		return count;
4173 
4174 	if (sscanf(buf, "%du", &wlan_en_delay) != 1) {
4175 		icnss_pr_err("Failed to read wlan_en_delay");
4176 		return -EINVAL;
4177 	}
4178 
4179 	icnss_pr_dbg("WLAN_EN delay: %dms", wlan_en_delay);
4180 	priv->wlan_en_delay_ms_user = wlan_en_delay;
4181 
4182 	return count;
4183 }
4184 
4185 static DEVICE_ATTR_WO(qdss_tr_start);
4186 static DEVICE_ATTR_WO(qdss_tr_stop);
4187 static DEVICE_ATTR_WO(qdss_conf_download);
4188 static DEVICE_ATTR_WO(hw_trc_override);
4189 static DEVICE_ATTR_WO(wpss_boot);
4190 static DEVICE_ATTR_WO(wlan_en_delay);
4191 
4192 static struct attribute *icnss_attrs[] = {
4193 	&dev_attr_qdss_tr_start.attr,
4194 	&dev_attr_qdss_tr_stop.attr,
4195 	&dev_attr_qdss_conf_download.attr,
4196 	&dev_attr_hw_trc_override.attr,
4197 	&dev_attr_wpss_boot.attr,
4198 	&dev_attr_wlan_en_delay.attr,
4199 	NULL,
4200 };
4201 
4202 static struct attribute_group icnss_attr_group = {
4203 	.attrs = icnss_attrs,
4204 };
4205 
icnss_create_sysfs_link(struct icnss_priv * priv)4206 static int icnss_create_sysfs_link(struct icnss_priv *priv)
4207 {
4208 	struct device *dev = &priv->pdev->dev;
4209 	int ret;
4210 
4211 	ret = sysfs_create_link(kernel_kobj, &dev->kobj, "icnss");
4212 	if (ret) {
4213 		icnss_pr_err("Failed to create icnss link, err = %d\n",
4214 			     ret);
4215 		goto out;
4216 	}
4217 
4218 	return 0;
4219 out:
4220 	return ret;
4221 }
4222 
icnss_remove_sysfs_link(struct icnss_priv * priv)4223 static void icnss_remove_sysfs_link(struct icnss_priv *priv)
4224 {
4225 	sysfs_remove_link(kernel_kobj, "icnss");
4226 }
4227 
4228 
4229 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0))
4230 union icnss_device_group_devres {
4231 	const struct attribute_group *group;
4232 };
4233 
devm_icnss_group_remove(struct device * dev,void * res)4234 static void devm_icnss_group_remove(struct device *dev, void *res)
4235 {
4236 	union icnss_device_group_devres *devres = res;
4237 	const struct attribute_group *group = devres->group;
4238 
4239 	icnss_pr_dbg("%s: removing group %p\n", __func__, group);
4240 	sysfs_remove_group(&dev->kobj, group);
4241 }
4242 
devm_icnss_group_match(struct device * dev,void * res,void * data)4243 static int devm_icnss_group_match(struct device *dev, void *res, void *data)
4244 {
4245 	return ((union icnss_device_group_devres *)res) == data;
4246 }
4247 
icnss_devm_device_remove_group(struct icnss_priv * priv)4248 static void icnss_devm_device_remove_group(struct icnss_priv *priv)
4249 {
4250 	WARN_ON(devres_release(&priv->pdev->dev,
4251 			       devm_icnss_group_remove, devm_icnss_group_match,
4252 			       (void *)&icnss_attr_group));
4253 }
4254 #else
icnss_devm_device_remove_group(struct icnss_priv * priv)4255 static void icnss_devm_device_remove_group(struct icnss_priv *priv)
4256 {
4257 	devm_device_remove_group(&priv->pdev->dev, &icnss_attr_group);
4258 }
4259 #endif
4260 
icnss_sysfs_create(struct icnss_priv * priv)4261 static int icnss_sysfs_create(struct icnss_priv *priv)
4262 {
4263 	int ret = 0;
4264 
4265 	ret = devm_device_add_group(&priv->pdev->dev,
4266 				    &icnss_attr_group);
4267 	if (ret) {
4268 		icnss_pr_err("Failed to create icnss device group, err = %d\n",
4269 			     ret);
4270 		goto out;
4271 	}
4272 
4273 	icnss_create_sysfs_link(priv);
4274 
4275 	ret = icnss_create_shutdown_sysfs(priv);
4276 	if (ret)
4277 		goto remove_icnss_group;
4278 
4279 	return 0;
4280 remove_icnss_group:
4281 	icnss_devm_device_remove_group(priv);
4282 out:
4283 	return ret;
4284 }
4285 
icnss_sysfs_destroy(struct icnss_priv * priv)4286 static void icnss_sysfs_destroy(struct icnss_priv *priv)
4287 {
4288 	icnss_destroy_shutdown_sysfs(priv);
4289 	icnss_remove_sysfs_link(priv);
4290 	icnss_devm_device_remove_group(priv);
4291 }
4292 
icnss_resource_parse(struct icnss_priv * priv)4293 static int icnss_resource_parse(struct icnss_priv *priv)
4294 {
4295 	int ret = 0, i = 0, irq = 0;
4296 	struct platform_device *pdev = priv->pdev;
4297 	struct device *dev = &pdev->dev;
4298 	struct resource *res;
4299 	u32 int_prop;
4300 
4301 	ret = icnss_get_vreg(priv);
4302 	if (ret) {
4303 		icnss_pr_err("Failed to get vreg, err = %d\n", ret);
4304 		goto out;
4305 	}
4306 
4307 	ret = icnss_get_clk(priv);
4308 	if (ret) {
4309 		icnss_pr_err("Failed to get clocks, err = %d\n", ret);
4310 		goto put_vreg;
4311 	}
4312 
4313 	if (of_property_read_bool(pdev->dev.of_node, "qcom,psf-supported")) {
4314 		ret = icnss_get_psf_info(priv);
4315 		if (ret < 0)
4316 			goto out;
4317 		priv->psf_supported = true;
4318 	}
4319 
4320 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
4321 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
4322 						   "membase");
4323 		if (!res) {
4324 			icnss_pr_err("Memory base not found in DT\n");
4325 			ret = -EINVAL;
4326 			goto put_clk;
4327 		}
4328 
4329 		priv->mem_base_pa = res->start;
4330 		priv->mem_base_va = devm_ioremap(dev, priv->mem_base_pa,
4331 						 resource_size(res));
4332 		if (!priv->mem_base_va) {
4333 			icnss_pr_err("Memory base ioremap failed: phy addr: %pa\n",
4334 				     &priv->mem_base_pa);
4335 			ret = -EINVAL;
4336 			goto put_clk;
4337 		}
4338 		icnss_pr_dbg("MEM_BASE pa: %pa, va: 0x%pK\n",
4339 			     &priv->mem_base_pa,
4340 			     priv->mem_base_va);
4341 
4342 		for (i = 0; i < ICNSS_MAX_IRQ_REGISTRATIONS; i++) {
4343 			irq = platform_get_irq(pdev, i);
4344 			if (irq < 0) {
4345 				icnss_pr_err("Fail to get IRQ-%d\n", i);
4346 				ret = -ENODEV;
4347 				goto put_clk;
4348 			} else {
4349 				priv->ce_irqs[i] = irq;
4350 			}
4351 		}
4352 
4353 		if (of_property_read_bool(pdev->dev.of_node,
4354 					  "qcom,is_low_power")) {
4355 			priv->low_power_support = true;
4356 			icnss_pr_dbg("Deep Sleep/Hibernate mode supported\n");
4357 		}
4358 
4359 		if (of_property_read_u32(pdev->dev.of_node, "qcom,rf_subtype",
4360 					 &priv->rf_subtype) == 0) {
4361 			priv->is_rf_subtype_valid = true;
4362 			icnss_pr_dbg("RF subtype 0x%x\n", priv->rf_subtype);
4363 		}
4364 
4365 		if (of_property_read_bool(pdev->dev.of_node,
4366 					  "qcom,is_slate_rfa")) {
4367 			priv->is_slate_rfa = true;
4368 			icnss_pr_err("SLATE rfa is enabled\n");
4369 		}
4370 	} else if (priv->device_id == WCN6750_DEVICE_ID ||
4371 		   priv->device_id == WCN6450_DEVICE_ID) {
4372 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
4373 						   "msi_addr");
4374 		if (!res) {
4375 			icnss_pr_err("MSI address not found in DT\n");
4376 			ret = -EINVAL;
4377 			goto put_clk;
4378 		}
4379 
4380 		priv->msi_addr_pa = res->start;
4381 		priv->msi_addr_iova = dma_map_resource(dev, priv->msi_addr_pa,
4382 						       PAGE_SIZE,
4383 						       DMA_FROM_DEVICE, 0);
4384 		if (dma_mapping_error(dev, priv->msi_addr_iova)) {
4385 			icnss_pr_err("MSI: failed to map msi address\n");
4386 			priv->msi_addr_iova = 0;
4387 			ret = -ENOMEM;
4388 			goto put_clk;
4389 		}
4390 		icnss_pr_dbg("MSI Addr pa: %pa, iova: 0x%pK\n",
4391 			     &priv->msi_addr_pa,
4392 			     priv->msi_addr_iova);
4393 
4394 		ret = of_property_read_u32_index(dev->of_node,
4395 						 "interrupts",
4396 						 1,
4397 						 &int_prop);
4398 		if (ret) {
4399 			icnss_pr_dbg("Read interrupt prop failed");
4400 			goto put_clk;
4401 		}
4402 
4403 		priv->msi_base_data = int_prop + 32;
4404 		icnss_pr_dbg(" MSI Base Data: %d, IRQ Index: %d\n",
4405 			     priv->msi_base_data, int_prop);
4406 
4407 		icnss_get_msi_assignment(priv);
4408 		for (i = 0; i < priv->msi_config->total_vectors; i++) {
4409 			irq = platform_get_irq(priv->pdev, i);
4410 			if (irq < 0) {
4411 				icnss_pr_err("Fail to get IRQ-%d\n", i);
4412 				ret = -ENODEV;
4413 				goto put_clk;
4414 			} else {
4415 				priv->srng_irqs[i] = irq;
4416 			}
4417 		}
4418 	}
4419 
4420 	return 0;
4421 
4422 put_clk:
4423 	icnss_put_clk(priv);
4424 put_vreg:
4425 	icnss_put_vreg(priv);
4426 out:
4427 	return ret;
4428 }
4429 
icnss_msa_dt_parse(struct icnss_priv * priv)4430 static int icnss_msa_dt_parse(struct icnss_priv *priv)
4431 {
4432 	int ret = 0;
4433 	struct platform_device *pdev = priv->pdev;
4434 	struct device *dev = &pdev->dev;
4435 	struct device_node *np = NULL;
4436 	u64 prop_size = 0;
4437 	const __be32 *addrp = NULL;
4438 
4439 	np = of_parse_phandle(dev->of_node,
4440 			      "qcom,wlan-msa-fixed-region", 0);
4441 	if (np) {
4442 		addrp = of_get_address(np, 0, &prop_size, NULL);
4443 		if (!addrp) {
4444 			icnss_pr_err("Failed to get assigned-addresses or property\n");
4445 			ret = -EINVAL;
4446 			of_node_put(np);
4447 			goto out;
4448 		}
4449 
4450 		priv->msa_pa = of_translate_address(np, addrp);
4451 		if (priv->msa_pa == OF_BAD_ADDR) {
4452 			icnss_pr_err("Failed to translate MSA PA from device-tree\n");
4453 			ret = -EINVAL;
4454 			of_node_put(np);
4455 			goto out;
4456 		}
4457 
4458 		of_node_put(np);
4459 
4460 		priv->msa_va = memremap(priv->msa_pa,
4461 					(unsigned long)prop_size, MEMREMAP_WT);
4462 		if (!priv->msa_va) {
4463 			icnss_pr_err("MSA PA ioremap failed: phy addr: %pa\n",
4464 				     &priv->msa_pa);
4465 			ret = -EINVAL;
4466 			goto out;
4467 		}
4468 		priv->msa_mem_size = prop_size;
4469 	} else {
4470 		ret = of_property_read_u32(dev->of_node, "qcom,wlan-msa-memory",
4471 					   &priv->msa_mem_size);
4472 		if (ret || priv->msa_mem_size == 0) {
4473 			icnss_pr_err("Fail to get MSA Memory Size: %u ret: %d\n",
4474 				     priv->msa_mem_size, ret);
4475 			goto out;
4476 		}
4477 
4478 		priv->msa_va = dmam_alloc_coherent(&pdev->dev,
4479 				priv->msa_mem_size, &priv->msa_pa, GFP_KERNEL);
4480 
4481 		if (!priv->msa_va) {
4482 			icnss_pr_err("DMA alloc failed for MSA\n");
4483 			ret = -ENOMEM;
4484 			goto out;
4485 		}
4486 	}
4487 
4488 	icnss_pr_dbg("MSA pa: %pa, MSA va: 0x%pK MSA Memory Size: 0x%x\n",
4489 		     &priv->msa_pa, (void *)priv->msa_va, priv->msa_mem_size);
4490 
4491 	priv->use_prefix_path = of_property_read_bool(priv->pdev->dev.of_node,
4492 						      "qcom,fw-prefix");
4493 	return 0;
4494 
4495 out:
4496 	return ret;
4497 }
4498 
icnss_smmu_fault_handler(struct iommu_domain * domain,struct device * dev,unsigned long iova,int flags,void * handler_token)4499 static int icnss_smmu_fault_handler(struct iommu_domain *domain,
4500 				    struct device *dev, unsigned long iova,
4501 				    int flags, void *handler_token)
4502 {
4503 	struct icnss_priv *priv = handler_token;
4504 	struct icnss_uevent_fw_down_data fw_down_data = {0};
4505 
4506 	icnss_fatal_err("SMMU fault happened with IOVA 0x%lx\n", iova);
4507 
4508 	if (!priv) {
4509 		icnss_pr_err("priv is NULL\n");
4510 		return -ENODEV;
4511 	}
4512 
4513 	if (test_bit(ICNSS_FW_READY, &priv->state)) {
4514 		fw_down_data.crashed = true;
4515 		icnss_call_driver_uevent(priv, ICNSS_UEVENT_SMMU_FAULT,
4516 					 &fw_down_data);
4517 		icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN,
4518 					 &fw_down_data);
4519 	}
4520 
4521 	icnss_trigger_recovery(&priv->pdev->dev);
4522 
4523 	/* IOMMU driver requires -ENOSYS return value to print debug info. */
4524 	return -ENOSYS;
4525 }
4526 
icnss_smmu_dt_parse(struct icnss_priv * priv)4527 static int icnss_smmu_dt_parse(struct icnss_priv *priv)
4528 {
4529 	int ret = 0;
4530 	struct platform_device *pdev = priv->pdev;
4531 	struct device *dev = &pdev->dev;
4532 	const char *iommu_dma_type;
4533 	struct resource *res;
4534 	u32 addr_win[2];
4535 
4536 	ret = of_property_read_u32_array(dev->of_node,
4537 					 "qcom,iommu-dma-addr-pool",
4538 					 addr_win,
4539 					 ARRAY_SIZE(addr_win));
4540 
4541 	if (ret) {
4542 		icnss_pr_err("SMMU IOVA base not found\n");
4543 	} else {
4544 		priv->smmu_iova_start = addr_win[0];
4545 		priv->smmu_iova_len = addr_win[1];
4546 		icnss_pr_dbg("SMMU IOVA start: %pa, len: %zx\n",
4547 			     &priv->smmu_iova_start,
4548 			     priv->smmu_iova_len);
4549 
4550 		priv->iommu_domain =
4551 			iommu_get_domain_for_dev(&pdev->dev);
4552 
4553 		ret = of_property_read_string(dev->of_node, "qcom,iommu-dma",
4554 					      &iommu_dma_type);
4555 		if (!ret && !strcmp("fastmap", iommu_dma_type)) {
4556 			icnss_pr_dbg("SMMU S1 stage enabled\n");
4557 			priv->smmu_s1_enable = true;
4558 			if (priv->device_id == WCN6750_DEVICE_ID ||
4559 			    priv->device_id == WCN6450_DEVICE_ID)
4560 				iommu_set_fault_handler(priv->iommu_domain,
4561 						icnss_smmu_fault_handler,
4562 						priv);
4563 		}
4564 
4565 		res = platform_get_resource_byname(pdev,
4566 						   IORESOURCE_MEM,
4567 						   "smmu_iova_ipa");
4568 		if (!res) {
4569 			icnss_pr_err("SMMU IOVA IPA not found\n");
4570 		} else {
4571 			priv->smmu_iova_ipa_start = res->start;
4572 			priv->smmu_iova_ipa_current = res->start;
4573 			priv->smmu_iova_ipa_len = resource_size(res);
4574 			icnss_pr_dbg("SMMU IOVA IPA start: %pa, len: %zx\n",
4575 				     &priv->smmu_iova_ipa_start,
4576 				     priv->smmu_iova_ipa_len);
4577 		}
4578 	}
4579 
4580 	return 0;
4581 }
4582 
icnss_get_iova(struct icnss_priv * priv,u64 * addr,u64 * size)4583 int icnss_get_iova(struct icnss_priv *priv, u64 *addr, u64 *size)
4584 {
4585 	if (!priv)
4586 		return -ENODEV;
4587 
4588 	if (!priv->smmu_iova_len)
4589 		return -EINVAL;
4590 
4591 	*addr = priv->smmu_iova_start;
4592 	*size = priv->smmu_iova_len;
4593 
4594 	return 0;
4595 }
4596 
icnss_get_iova_ipa(struct icnss_priv * priv,u64 * addr,u64 * size)4597 int icnss_get_iova_ipa(struct icnss_priv *priv, u64 *addr, u64 *size)
4598 {
4599 	if (!priv)
4600 		return -ENODEV;
4601 
4602 	if (!priv->smmu_iova_ipa_len)
4603 		return -EINVAL;
4604 
4605 	*addr = priv->smmu_iova_ipa_start;
4606 	*size = priv->smmu_iova_ipa_len;
4607 
4608 	return 0;
4609 }
4610 
icnss_add_fw_prefix_name(struct icnss_priv * priv,char * prefix_name,char * name)4611 void icnss_add_fw_prefix_name(struct icnss_priv *priv, char *prefix_name,
4612 			      char *name)
4613 {
4614 	if (!priv)
4615 		return;
4616 
4617 	if (!priv->use_prefix_path) {
4618 		scnprintf(prefix_name, ICNSS_MAX_FILE_NAME, "%s", name);
4619 		return;
4620 	}
4621 
4622 	if (priv->device_id == ADRASTEA_DEVICE_ID)
4623 		scnprintf(prefix_name, ICNSS_MAX_FILE_NAME,
4624 			  ADRASTEA_PATH_PREFIX "%s", name);
4625 	else if (priv->device_id == WCN6750_DEVICE_ID)
4626 		scnprintf(prefix_name, ICNSS_MAX_FILE_NAME,
4627 			  QCA6750_PATH_PREFIX "%s", name);
4628 	else if (priv->device_id == WCN6450_DEVICE_ID)
4629 		scnprintf(prefix_name, ICNSS_MAX_FILE_NAME,
4630 			  WCN6450_PATH_PREFIX "%s", name);
4631 	icnss_pr_dbg("File added with prefix: %s\n", prefix_name);
4632 }
4633 
4634 static const struct platform_device_id icnss_platform_id_table[] = {
4635 	{ .name = "wcn6750", .driver_data = WCN6750_DEVICE_ID, },
4636 	{ .name = "adrastea", .driver_data = ADRASTEA_DEVICE_ID, },
4637 	{ .name = "wcn6450", .driver_data = WCN6450_DEVICE_ID, },
4638 	{ },
4639 };
4640 
4641 static const struct of_device_id icnss_dt_match[] = {
4642 	{
4643 		.compatible = "qcom,wcn6750",
4644 		.data = (void *)&icnss_platform_id_table[0]},
4645 	{
4646 		.compatible = "qcom,icnss",
4647 		.data = (void *)&icnss_platform_id_table[1]},
4648 	{
4649 		.compatible = "qcom,wcn6450",
4650 		.data = (void *)&icnss_platform_id_table[2]},
4651 	{ },
4652 };
4653 
4654 MODULE_DEVICE_TABLE(of, icnss_dt_match);
4655 
icnss_init_control_params(struct icnss_priv * priv)4656 static void icnss_init_control_params(struct icnss_priv *priv)
4657 {
4658 	priv->ctrl_params.qmi_timeout = WLFW_TIMEOUT;
4659 	priv->ctrl_params.quirks = ICNSS_QUIRKS_DEFAULT;
4660 	priv->ctrl_params.bdf_type = ICNSS_BDF_TYPE_DEFAULT;
4661 
4662 	if (priv->device_id == WCN6750_DEVICE_ID ||
4663 	    priv->device_id == WCN6450_DEVICE_ID ||
4664 	    of_property_read_bool(priv->pdev->dev.of_node,
4665 				  "wpss-support-enable"))
4666 		priv->wpss_supported = true;
4667 
4668 	if (of_property_read_bool(priv->pdev->dev.of_node,
4669 				  "bdf-download-support"))
4670 		priv->bdf_download_support = true;
4671 
4672 	if (of_property_read_bool(priv->pdev->dev.of_node,
4673 				  "rproc-fw-download"))
4674 		priv->rproc_fw_download = true;
4675 
4676 	if (priv->bdf_download_support && priv->device_id == ADRASTEA_DEVICE_ID)
4677 		priv->ctrl_params.bdf_type = ICNSS_BDF_BIN;
4678 }
4679 
icnss_read_device_configs(struct icnss_priv * priv)4680 static void icnss_read_device_configs(struct icnss_priv *priv)
4681 {
4682 	if (of_property_read_bool(priv->pdev->dev.of_node,
4683 				  "wlan-ipa-disabled")) {
4684 		set_bit(ICNSS_IPA_DISABLED, &priv->device_config);
4685 	}
4686 
4687 	if (of_property_read_bool(priv->pdev->dev.of_node,
4688 				  "qcom,wpss-self-recovery"))
4689 		priv->wpss_self_recovery_enabled = true;
4690 }
4691 
icnss_runtime_pm_init(struct icnss_priv * priv)4692 static inline void icnss_runtime_pm_init(struct icnss_priv *priv)
4693 {
4694 	pm_runtime_get_sync(&priv->pdev->dev);
4695 	pm_runtime_forbid(&priv->pdev->dev);
4696 	pm_runtime_set_active(&priv->pdev->dev);
4697 	pm_runtime_enable(&priv->pdev->dev);
4698 }
4699 
icnss_runtime_pm_deinit(struct icnss_priv * priv)4700 static inline void icnss_runtime_pm_deinit(struct icnss_priv *priv)
4701 {
4702 	pm_runtime_disable(&priv->pdev->dev);
4703 	pm_runtime_allow(&priv->pdev->dev);
4704 	pm_runtime_put_sync(&priv->pdev->dev);
4705 }
4706 
icnss_use_nv_mac(struct icnss_priv * priv)4707 static inline bool icnss_use_nv_mac(struct icnss_priv *priv)
4708 {
4709 	return of_property_read_bool(priv->pdev->dev.of_node,
4710 				     "use-nv-mac");
4711 }
4712 
rproc_restart_level_notifier(void * data,struct rproc * rproc)4713 static void rproc_restart_level_notifier(void *data, struct rproc *rproc)
4714 {
4715 	struct icnss_subsys_restart_level_data *restart_level_data;
4716 
4717 	icnss_pr_info("rproc name: %s recovery disable: %d",
4718 		      rproc->name, rproc->recovery_disabled);
4719 
4720 	restart_level_data = kzalloc(sizeof(*restart_level_data), GFP_ATOMIC);
4721 	if (!restart_level_data)
4722 		return;
4723 
4724 	if (strnstr(rproc->name, "wpss", ICNSS_RPROC_LEN)) {
4725 		if (rproc->recovery_disabled)
4726 			restart_level_data->restart_level = ICNSS_DISABLE_M3_SSR;
4727 		else
4728 			restart_level_data->restart_level = ICNSS_ENABLE_M3_SSR;
4729 
4730 		icnss_driver_event_post(penv, ICNSS_DRIVER_EVENT_SUBSYS_RESTART_LEVEL,
4731 					0, restart_level_data);
4732 	}
4733 }
4734 
4735 #if IS_ENABLED(CONFIG_WCNSS_MEM_PRE_ALLOC)
icnss_initialize_mem_pool(unsigned long device_id)4736 static void icnss_initialize_mem_pool(unsigned long device_id)
4737 {
4738 	cnss_initialize_prealloc_pool(device_id);
4739 }
icnss_deinitialize_mem_pool(void)4740 static void icnss_deinitialize_mem_pool(void)
4741 {
4742 	cnss_deinitialize_prealloc_pool();
4743 }
4744 #else
icnss_initialize_mem_pool(unsigned long device_id)4745 static void icnss_initialize_mem_pool(unsigned long device_id)
4746 {
4747 }
icnss_deinitialize_mem_pool(void)4748 static void icnss_deinitialize_mem_pool(void)
4749 {
4750 }
4751 #endif
4752 
register_rproc_restart_level_notifier(void)4753 static void register_rproc_restart_level_notifier(void)
4754 {
4755 	register_trace_android_vh_rproc_recovery_set(rproc_restart_level_notifier, NULL);
4756 }
4757 
unregister_rproc_restart_level_notifier(void)4758 static void unregister_rproc_restart_level_notifier(void)
4759 {
4760 	unregister_trace_android_vh_rproc_recovery_set(rproc_restart_level_notifier, NULL);
4761 }
4762 
icnss_probe(struct platform_device * pdev)4763 static int icnss_probe(struct platform_device *pdev)
4764 {
4765 	int ret = 0;
4766 	struct device *dev = &pdev->dev;
4767 	struct icnss_priv *priv;
4768 	const struct of_device_id *of_id;
4769 	const struct platform_device_id *device_id;
4770 
4771 	if (dev_get_drvdata(dev)) {
4772 		icnss_pr_err("Driver is already initialized\n");
4773 		return -EEXIST;
4774 	}
4775 
4776 	of_id = of_match_device(icnss_dt_match, &pdev->dev);
4777 	if (!of_id || !of_id->data) {
4778 		icnss_pr_err("Failed to find of match device!\n");
4779 		ret = -ENODEV;
4780 		goto out_reset_drvdata;
4781 	}
4782 
4783 	device_id = of_id->data;
4784 
4785 	icnss_pr_dbg("Platform driver probe\n");
4786 
4787 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
4788 	if (!priv)
4789 		return -ENOMEM;
4790 
4791 	priv->magic = ICNSS_MAGIC;
4792 	dev_set_drvdata(dev, priv);
4793 
4794 	priv->pdev = pdev;
4795 	priv->device_id = device_id->driver_data;
4796 	priv->is_chain1_supported = true;
4797 	INIT_LIST_HEAD(&priv->vreg_list);
4798 	INIT_LIST_HEAD(&priv->clk_list);
4799 	icnss_allow_recursive_recovery(dev);
4800 
4801 	icnss_initialize_mem_pool(priv->device_id);
4802 
4803 	icnss_init_control_params(priv);
4804 
4805 	icnss_read_device_configs(priv);
4806 
4807 	ret = icnss_resource_parse(priv);
4808 	if (ret)
4809 		goto out_reset_drvdata;
4810 
4811 	ret = icnss_msa_dt_parse(priv);
4812 	if (ret)
4813 		goto out_free_resources;
4814 
4815 	ret = icnss_smmu_dt_parse(priv);
4816 	if (ret)
4817 		goto out_free_resources;
4818 
4819 	spin_lock_init(&priv->event_lock);
4820 	spin_lock_init(&priv->on_off_lock);
4821 	spin_lock_init(&priv->soc_wake_msg_lock);
4822 	mutex_init(&priv->dev_lock);
4823 	mutex_init(&priv->tcdev_lock);
4824 
4825 	priv->event_wq = alloc_workqueue("icnss_driver_event", WQ_UNBOUND, 1);
4826 	if (!priv->event_wq) {
4827 		icnss_pr_err("Workqueue creation failed\n");
4828 		ret = -EFAULT;
4829 		goto smmu_cleanup;
4830 	}
4831 
4832 	INIT_WORK(&priv->event_work, icnss_driver_event_work);
4833 	INIT_LIST_HEAD(&priv->event_list);
4834 
4835 	if (priv->is_slate_rfa)
4836 		init_completion(&priv->slate_boot_complete);
4837 
4838 	ret = icnss_register_fw_service(priv);
4839 	if (ret < 0) {
4840 		icnss_pr_err("fw service registration failed: %d\n", ret);
4841 		goto out_destroy_wq;
4842 	}
4843 	icnss_power_misc_params_init(priv);
4844 
4845 	icnss_enable_recovery(priv);
4846 
4847 	icnss_debugfs_create(priv);
4848 
4849 	icnss_sysfs_create(priv);
4850 
4851 	ret = device_init_wakeup(&priv->pdev->dev, true);
4852 	if (ret)
4853 		icnss_pr_err("Failed to init platform device wakeup source, err = %d\n",
4854 			     ret);
4855 
4856 	icnss_set_plat_priv(priv);
4857 
4858 	init_completion(&priv->unblock_shutdown);
4859 
4860 	if (priv->device_id == WCN6750_DEVICE_ID ||
4861 	    priv->device_id == WCN6450_DEVICE_ID) {
4862 		priv->soc_wake_wq = alloc_workqueue("icnss_soc_wake_event",
4863 						    WQ_UNBOUND|WQ_HIGHPRI, 1);
4864 		if (!priv->soc_wake_wq) {
4865 			icnss_pr_err("Soc wake Workqueue creation failed\n");
4866 			ret = -EFAULT;
4867 			goto out_unregister_fw_service;
4868 		}
4869 
4870 		INIT_WORK(&priv->soc_wake_msg_work, icnss_soc_wake_msg_work);
4871 		INIT_LIST_HEAD(&priv->soc_wake_msg_list);
4872 
4873 		ret = icnss_genl_init();
4874 		if (ret < 0)
4875 			icnss_pr_err("ICNSS genl init failed %d\n", ret);
4876 
4877 		init_completion(&priv->smp2p_soc_wake_wait);
4878 		icnss_runtime_pm_init(priv);
4879 		icnss_aop_interface_init(priv);
4880 		set_bit(ICNSS_COLD_BOOT_CAL, &priv->state);
4881 		priv->bdf_download_support = true;
4882 		register_rproc_restart_level_notifier();
4883 	}
4884 
4885 	if (priv->wpss_supported) {
4886 		ret = icnss_dms_init(priv);
4887 		if (ret)
4888 			icnss_pr_err("ICNSS DMS init failed %d\n", ret);
4889 		priv->use_nv_mac = icnss_use_nv_mac(priv);
4890 		icnss_pr_dbg("NV MAC feature is %s\n",
4891 			     priv->use_nv_mac ? "Mandatory":"Not Mandatory");
4892 	}
4893 
4894 	if (priv->wpss_supported || priv->rproc_fw_download)
4895 		INIT_WORK(&wpss_loader, icnss_wpss_load);
4896 
4897 	timer_setup(&priv->recovery_timer,
4898 		    icnss_recovery_timeout_hdlr, 0);
4899 
4900 	if (priv->wpss_self_recovery_enabled) {
4901 		INIT_WORK(&wpss_ssr_work, icnss_wpss_self_recovery);
4902 		timer_setup(&priv->wpss_ssr_timer,
4903 			    icnss_wpss_ssr_timeout_hdlr, 0);
4904 	}
4905 
4906 	icnss_register_ims_service(priv);
4907 	INIT_LIST_HEAD(&priv->icnss_tcdev_list);
4908 
4909 	icnss_pr_info("Platform driver probed successfully\n");
4910 
4911 	return 0;
4912 
4913 out_unregister_fw_service:
4914 	icnss_unregister_fw_service(priv);
4915 out_destroy_wq:
4916 	destroy_workqueue(priv->event_wq);
4917 smmu_cleanup:
4918 	priv->iommu_domain = NULL;
4919 out_free_resources:
4920 	icnss_put_resources(priv);
4921 out_reset_drvdata:
4922 	icnss_deinitialize_mem_pool();
4923 	dev_set_drvdata(dev, NULL);
4924 	return ret;
4925 }
4926 
icnss_destroy_ramdump_device(struct icnss_ramdump_info * ramdump_info)4927 void icnss_destroy_ramdump_device(struct icnss_ramdump_info *ramdump_info)
4928 {
4929 
4930 	if (IS_ERR_OR_NULL(ramdump_info))
4931 		return;
4932 
4933 	device_unregister(ramdump_info->dev);
4934 
4935 	ida_simple_remove(&rd_minor_id, ramdump_info->minor);
4936 
4937 	kfree(ramdump_info);
4938 }
4939 
icnss_unregister_power_supply_notifier(struct icnss_priv * priv)4940 static void icnss_unregister_power_supply_notifier(struct icnss_priv *priv)
4941 {
4942 	if (priv->batt_psy)
4943 		power_supply_put(penv->batt_psy);
4944 
4945 	if (priv->psf_supported) {
4946 		flush_workqueue(priv->soc_update_wq);
4947 		destroy_workqueue(priv->soc_update_wq);
4948 		power_supply_unreg_notifier(&priv->psf_nb);
4949 	}
4950 }
4951 
icnss_remove(struct platform_device * pdev)4952 static int icnss_remove(struct platform_device *pdev)
4953 {
4954 	struct icnss_priv *priv = dev_get_drvdata(&pdev->dev);
4955 
4956 	icnss_pr_info("Removing driver: state: 0x%lx\n", priv->state);
4957 
4958 	del_timer(&priv->recovery_timer);
4959 
4960 	if (priv->wpss_self_recovery_enabled)
4961 		del_timer(&priv->wpss_ssr_timer);
4962 
4963 	device_init_wakeup(&priv->pdev->dev, false);
4964 
4965 	icnss_unregister_ims_service(priv);
4966 
4967 	icnss_debugfs_destroy(priv);
4968 
4969 	icnss_unregister_power_supply_notifier(penv);
4970 
4971 	icnss_sysfs_destroy(priv);
4972 
4973 	complete_all(&priv->unblock_shutdown);
4974 
4975 	if (priv->is_slate_rfa) {
4976 		complete(&priv->slate_boot_complete);
4977 		icnss_slate_ssr_unregister_notifier(priv);
4978 		icnss_unregister_slate_event_notifier(priv);
4979 	}
4980 
4981 	icnss_destroy_ramdump_device(priv->msa0_dump_dev);
4982 
4983 	if (priv->wpss_supported) {
4984 		icnss_dms_deinit(priv);
4985 		icnss_wpss_early_ssr_unregister_notifier(priv);
4986 		icnss_wpss_ssr_unregister_notifier(priv);
4987 	} else {
4988 		icnss_modem_ssr_unregister_notifier(priv);
4989 		icnss_pdr_unregister_notifier(priv);
4990 	}
4991 
4992 	if (priv->device_id == WCN6750_DEVICE_ID ||
4993 	    priv->device_id == WCN6450_DEVICE_ID) {
4994 		icnss_genl_exit();
4995 		icnss_runtime_pm_deinit(priv);
4996 		unregister_rproc_restart_level_notifier();
4997 		complete_all(&priv->smp2p_soc_wake_wait);
4998 		icnss_destroy_ramdump_device(priv->m3_dump_phyareg);
4999 		icnss_destroy_ramdump_device(priv->m3_dump_phydbg);
5000 		icnss_destroy_ramdump_device(priv->m3_dump_wmac0reg);
5001 		icnss_destroy_ramdump_device(priv->m3_dump_wcssdbg);
5002 		icnss_destroy_ramdump_device(priv->m3_dump_phyapdmem);
5003 		if (priv->soc_wake_wq)
5004 			destroy_workqueue(priv->soc_wake_wq);
5005 		icnss_aop_interface_deinit(priv);
5006 	}
5007 
5008 	class_destroy(priv->icnss_ramdump_class);
5009 	unregister_chrdev_region(priv->icnss_ramdump_dev, RAMDUMP_NUM_DEVICES);
5010 
5011 	icnss_unregister_fw_service(priv);
5012 	if (priv->event_wq)
5013 		destroy_workqueue(priv->event_wq);
5014 
5015 	priv->iommu_domain = NULL;
5016 
5017 	icnss_hw_power_off(priv);
5018 
5019 	icnss_put_resources(priv);
5020 
5021 	icnss_deinitialize_mem_pool();
5022 
5023 	dev_set_drvdata(&pdev->dev, NULL);
5024 
5025 	return 0;
5026 }
5027 
icnss_recovery_timeout_hdlr(struct timer_list * t)5028 void icnss_recovery_timeout_hdlr(struct timer_list *t)
5029 {
5030 	struct icnss_priv *priv = from_timer(priv, t, recovery_timer);
5031 
5032 	/* This is to handle if slate is not up and modem SSR is triggered */
5033 	if (priv->is_slate_rfa && !test_bit(ICNSS_SLATE_UP, &priv->state))
5034 		return;
5035 
5036 	icnss_pr_err("Timeout waiting for FW Ready 0x%lx\n", priv->state);
5037 	ICNSS_ASSERT(0);
5038 }
5039 
icnss_wpss_ssr_timeout_hdlr(struct timer_list * t)5040 void icnss_wpss_ssr_timeout_hdlr(struct timer_list *t)
5041 {
5042 	struct icnss_priv *priv = from_timer(priv, t, wpss_ssr_timer);
5043 
5044 	icnss_pr_err("Timeout waiting for WPSS SSR notification 0x%lx\n",
5045 		      priv->state);
5046 	schedule_work(&wpss_ssr_work);
5047 }
5048 
5049 #ifdef CONFIG_PM_SLEEP
icnss_pm_suspend(struct device * dev)5050 static int icnss_pm_suspend(struct device *dev)
5051 {
5052 	struct icnss_priv *priv = dev_get_drvdata(dev);
5053 	int ret = 0;
5054 
5055 	if (priv->magic != ICNSS_MAGIC) {
5056 		icnss_pr_err("Invalid drvdata for pm suspend: dev %pK, data %pK, magic 0x%x\n",
5057 			     dev, priv, priv->magic);
5058 		return -EINVAL;
5059 	}
5060 
5061 	icnss_pr_vdbg("PM Suspend, state: 0x%lx\n", priv->state);
5062 
5063 	if (!priv->ops || !priv->ops->pm_suspend ||
5064 	    icnss_is_smp2p_valid(priv, ICNSS_SMP2P_OUT_POWER_SAVE) ||
5065 	    !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
5066 		return 0;
5067 
5068 	ret = priv->ops->pm_suspend(dev);
5069 
5070 	if (ret == 0) {
5071 		if (priv->device_id == WCN6750_DEVICE_ID ||
5072 		    priv->device_id == WCN6450_DEVICE_ID) {
5073 			if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
5074 			    !test_bit(ICNSS_MODE_ON, &priv->state))
5075 				return 0;
5076 
5077 			ret = icnss_send_smp2p(priv, ICNSS_POWER_SAVE_ENTER,
5078 					       ICNSS_SMP2P_OUT_POWER_SAVE);
5079 		}
5080 		priv->stats.pm_suspend++;
5081 		set_bit(ICNSS_PM_SUSPEND, &priv->state);
5082 	} else {
5083 		priv->stats.pm_suspend_err++;
5084 	}
5085 	return ret;
5086 }
5087 
icnss_pm_resume(struct device * dev)5088 static int icnss_pm_resume(struct device *dev)
5089 {
5090 	struct icnss_priv *priv = dev_get_drvdata(dev);
5091 	int ret = 0;
5092 
5093 	if (priv->magic != ICNSS_MAGIC) {
5094 		icnss_pr_err("Invalid drvdata for pm resume: dev %pK, data %pK, magic 0x%x\n",
5095 			     dev, priv, priv->magic);
5096 		return -EINVAL;
5097 	}
5098 
5099 	icnss_pr_vdbg("PM resume, state: 0x%lx\n", priv->state);
5100 
5101 	if (!priv->ops || !priv->ops->pm_resume ||
5102 	    icnss_is_smp2p_valid(priv, ICNSS_SMP2P_OUT_POWER_SAVE) ||
5103 	    !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
5104 		goto out;
5105 
5106 	ret = priv->ops->pm_resume(dev);
5107 
5108 out:
5109 	if (ret == 0) {
5110 		priv->stats.pm_resume++;
5111 		clear_bit(ICNSS_PM_SUSPEND, &priv->state);
5112 	} else {
5113 		priv->stats.pm_resume_err++;
5114 	}
5115 	return ret;
5116 }
5117 
icnss_pm_suspend_noirq(struct device * dev)5118 static int icnss_pm_suspend_noirq(struct device *dev)
5119 {
5120 	struct icnss_priv *priv = dev_get_drvdata(dev);
5121 	int ret = 0;
5122 
5123 	if (priv->magic != ICNSS_MAGIC) {
5124 		icnss_pr_err("Invalid drvdata for pm suspend_noirq: dev %pK, data %pK, magic 0x%x\n",
5125 			     dev, priv, priv->magic);
5126 		return -EINVAL;
5127 	}
5128 
5129 	icnss_pr_vdbg("PM suspend_noirq, state: 0x%lx\n", priv->state);
5130 
5131 	if (!priv->ops || !priv->ops->suspend_noirq ||
5132 	    !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
5133 		goto out;
5134 
5135 	ret = priv->ops->suspend_noirq(dev);
5136 
5137 out:
5138 	if (ret == 0) {
5139 		priv->stats.pm_suspend_noirq++;
5140 		set_bit(ICNSS_PM_SUSPEND_NOIRQ, &priv->state);
5141 	} else {
5142 		priv->stats.pm_suspend_noirq_err++;
5143 	}
5144 	return ret;
5145 }
5146 
icnss_pm_resume_noirq(struct device * dev)5147 static int icnss_pm_resume_noirq(struct device *dev)
5148 {
5149 	struct icnss_priv *priv = dev_get_drvdata(dev);
5150 	int ret = 0;
5151 
5152 	if (priv->magic != ICNSS_MAGIC) {
5153 		icnss_pr_err("Invalid drvdata for pm resume_noirq: dev %pK, data %pK, magic 0x%x\n",
5154 			     dev, priv, priv->magic);
5155 		return -EINVAL;
5156 	}
5157 
5158 	icnss_pr_vdbg("PM resume_noirq, state: 0x%lx\n", priv->state);
5159 
5160 	if (!priv->ops || !priv->ops->resume_noirq ||
5161 	    !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
5162 		goto out;
5163 
5164 	ret = priv->ops->resume_noirq(dev);
5165 
5166 out:
5167 	if (ret == 0) {
5168 		priv->stats.pm_resume_noirq++;
5169 		clear_bit(ICNSS_PM_SUSPEND_NOIRQ, &priv->state);
5170 	} else {
5171 		priv->stats.pm_resume_noirq_err++;
5172 	}
5173 	return ret;
5174 }
5175 
icnss_pm_runtime_suspend(struct device * dev)5176 static int icnss_pm_runtime_suspend(struct device *dev)
5177 {
5178 	struct icnss_priv *priv = dev_get_drvdata(dev);
5179 	int ret = 0;
5180 
5181 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
5182 		icnss_pr_err("Ignore runtime suspend:\n");
5183 		goto out;
5184 	}
5185 
5186 	if (priv->magic != ICNSS_MAGIC) {
5187 		icnss_pr_err("Invalid drvdata for runtime suspend: dev %pK, data %pK, magic 0x%x\n",
5188 			     dev, priv, priv->magic);
5189 		return -EINVAL;
5190 	}
5191 
5192 	if (!priv->ops || !priv->ops->runtime_suspend ||
5193 	    icnss_is_smp2p_valid(priv, ICNSS_SMP2P_OUT_POWER_SAVE))
5194 		goto out;
5195 
5196 	icnss_pr_vdbg("Runtime suspend\n");
5197 	ret = priv->ops->runtime_suspend(dev);
5198 	if (!ret) {
5199 		if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
5200 		    !test_bit(ICNSS_MODE_ON, &priv->state))
5201 			return 0;
5202 
5203 		ret = icnss_send_smp2p(priv, ICNSS_POWER_SAVE_ENTER,
5204 				       ICNSS_SMP2P_OUT_POWER_SAVE);
5205 	}
5206 out:
5207 	return ret;
5208 }
5209 
icnss_pm_runtime_resume(struct device * dev)5210 static int icnss_pm_runtime_resume(struct device *dev)
5211 {
5212 	struct icnss_priv *priv = dev_get_drvdata(dev);
5213 	int ret = 0;
5214 
5215 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
5216 		icnss_pr_err("Ignore runtime resume\n");
5217 		goto out;
5218 	}
5219 
5220 	if (priv->magic != ICNSS_MAGIC) {
5221 		icnss_pr_err("Invalid drvdata for runtime resume: dev %pK, data %pK, magic 0x%x\n",
5222 			     dev, priv, priv->magic);
5223 		return -EINVAL;
5224 	}
5225 
5226 	if (!priv->ops || !priv->ops->runtime_resume ||
5227 	    icnss_is_smp2p_valid(priv, ICNSS_SMP2P_OUT_POWER_SAVE))
5228 		goto out;
5229 
5230 	icnss_pr_vdbg("Runtime resume, state: 0x%lx\n", priv->state);
5231 
5232 	ret = priv->ops->runtime_resume(dev);
5233 
5234 out:
5235 	return ret;
5236 }
5237 
icnss_pm_runtime_idle(struct device * dev)5238 static int icnss_pm_runtime_idle(struct device *dev)
5239 {
5240 	struct icnss_priv *priv = dev_get_drvdata(dev);
5241 
5242 	if (priv->device_id == ADRASTEA_DEVICE_ID) {
5243 		icnss_pr_err("Ignore runtime idle\n");
5244 		goto out;
5245 	}
5246 
5247 	icnss_pr_vdbg("Runtime idle\n");
5248 
5249 	pm_request_autosuspend(dev);
5250 
5251 out:
5252 	return -EBUSY;
5253 }
5254 #endif
5255 
5256 static const struct dev_pm_ops icnss_pm_ops = {
5257 	SET_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend,
5258 				icnss_pm_resume)
5259 	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend_noirq,
5260 				      icnss_pm_resume_noirq)
5261 	SET_RUNTIME_PM_OPS(icnss_pm_runtime_suspend, icnss_pm_runtime_resume,
5262 			   icnss_pm_runtime_idle)
5263 };
5264 
5265 static struct platform_driver icnss_driver = {
5266 	.probe  = icnss_probe,
5267 	.remove = icnss_remove,
5268 	.driver = {
5269 		.name = "icnss2",
5270 		.pm = &icnss_pm_ops,
5271 		.of_match_table = icnss_dt_match,
5272 	},
5273 };
5274 
icnss_initialize(void)5275 static int __init icnss_initialize(void)
5276 {
5277 	icnss_debug_init();
5278 	return platform_driver_register(&icnss_driver);
5279 }
5280 
icnss_exit(void)5281 static void __exit icnss_exit(void)
5282 {
5283 	platform_driver_unregister(&icnss_driver);
5284 	icnss_debug_deinit();
5285 }
5286 
5287 
5288 module_init(icnss_initialize);
5289 module_exit(icnss_exit);
5290 
5291 MODULE_LICENSE("GPL v2");
5292 MODULE_DESCRIPTION("iWCN CORE platform driver");
5293