1 /****************************************************************************
3 * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 * Chip Manager interface
7 ****************************************************************************/
12 #include "scsc_wifi_cm_if.h"
13 #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING
14 #include "hip4_sampler.h"
17 #include <scsc/scsc_mx.h>
18 #ifdef CONFIG_SCSC_LOG_COLLECTION
19 #include <scsc/scsc_log_collector.h>
22 static bool EnableTestMode
;
23 module_param(EnableTestMode
, bool, S_IRUGO
| S_IWUSR
);
24 MODULE_PARM_DESC(EnableTestMode
, "Enable WlanLite test mode driver.");
26 static BLOCKING_NOTIFIER_HEAD(slsi_wlan_notifier
);
28 static bool EnableRfTestMode
;
29 module_param(EnableRfTestMode
, bool, S_IRUGO
| S_IWUSR
);
30 MODULE_PARM_DESC(EnableRfTestMode
, "Enable RF test mode driver.");
32 static struct mutex slsi_start_mutex
;
33 static int recovery_in_progress
;
34 static u16 latest_scsc_panic_code
;
36 /* TODO: Would be good to get this removed - use module_client? */
38 struct slsi_dev
*sdev
;
41 /* Only one wlan service instance is assumed for now. */
42 static struct slsi_cm_ctx cm_ctx
;
44 static void slsi_hip_block_bh(struct slsi_dev
*sdev
);
46 int slsi_wlan_service_notifier_register(struct notifier_block
*nb
)
48 return blocking_notifier_chain_register(&slsi_wlan_notifier
, nb
);
51 int slsi_wlan_service_notifier_unregister(struct notifier_block
*nb
)
53 return blocking_notifier_chain_unregister(&slsi_wlan_notifier
, nb
);
56 static int wlan_suspend(struct scsc_service_client
*client
)
58 struct slsi_dev
*sdev
= container_of(client
, struct slsi_dev
, mx_wlan_client
);
60 SLSI_INFO_NODEV("Nofity registered functions\n");
61 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_SUSPEND
, sdev
);
66 static int wlan_resume(struct scsc_service_client
*client
)
68 struct slsi_dev
*sdev
= container_of(client
, struct slsi_dev
, mx_wlan_client
);
70 SLSI_INFO_NODEV("Nofity registered functions\n");
71 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_RESUME
, sdev
);
76 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
77 static u8
wlan_failure_notification(struct scsc_service_client
*client
, struct mx_syserr_decode
*err
)
79 struct slsi_dev
*sdev
= container_of(client
, struct slsi_dev
, mx_wlan_client
);
80 struct netdev_vif
*ndev_vif
;
81 struct net_device
*dev
;
83 atomic_set(&sdev
->cm_if
.reset_level
, err
->level
);
84 SLSI_INFO_NODEV("SubSystem:%d,Level:%d,Type:%d,Sub_code:%d\n", err
->subsys
, err
->level
, err
->type
, err
->subcode
);
85 /* system recovery not tested for p2p. So raise it to highest level for now. */
86 dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2PX_SWLAN
);
88 ndev_vif
= netdev_priv(dev
);
89 if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev
, ndev_vif
))
90 return SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC
;
95 static void wlan_failure_reset_v2(struct scsc_service_client
*client
, u8 level
, u16 scsc_syserr_code
)
97 struct slsi_dev
*sdev
= container_of(client
, struct slsi_dev
, mx_wlan_client
);
99 SLSI_INFO_NODEV("Level:%d scsc_syserr_code:%d\n", level
, scsc_syserr_code
);
100 mutex_lock(&slsi_start_mutex
);
101 atomic_set(&sdev
->cm_if
.reset_level
, level
);
102 mutex_unlock(&slsi_start_mutex
);
104 SLSI_WARN_NODEV("Low level error level:%d\n", level
);
105 if (level
== 5 || level
== 6)
106 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_SUBSYSTEM_RESET
, sdev
);
109 static void wlan_failure_reset(struct scsc_service_client
*client
, u16 scsc_panic_code
)
111 SLSI_INFO_NODEV("\n");
112 latest_scsc_panic_code
= scsc_panic_code
;
115 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
116 static bool wlan_stop_on_failure_v2(struct scsc_service_client
*client
, struct mx_syserr_decode
*err
)
119 struct slsi_dev
*sdev
= container_of(client
, struct slsi_dev
, mx_wlan_client
);
121 SLSI_INFO_NODEV("\n");
123 mutex_lock(&slsi_start_mutex
);
124 recovery_in_progress
= 1;
125 sdev
->recovery_status
= 1;
126 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
127 atomic_set(&sdev
->cm_if
.reset_level
, err
->level
);
128 if (state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
) {
129 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_BLOCKED
);
130 sdev
->fail_reported
= true;
132 /* If next state is stopped, then don't signal recovery since
133 * the Android framework won't/shouldn't restart (supplicant
136 if (sdev
->recovery_next_state
!= SCSC_WIFI_CM_IF_STATE_STOPPING
) {
137 slsi_hip_block_bh(sdev
);
139 /* Stop wlan operations. Send event to registered parties */
140 mutex_unlock(&slsi_start_mutex
);
141 SLSI_INFO_NODEV("Nofity registered functions\n");
142 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_STOP
, sdev
);
143 mutex_lock(&slsi_start_mutex
);
146 SLSI_INFO_NODEV("Wi-Fi service driver not started\n");
149 mutex_unlock(&slsi_start_mutex
);
153 static void wlan_stop_on_failure(struct scsc_service_client
*client
)
157 u8 system_error_level
;
158 struct slsi_dev
*sdev
= container_of(client
, struct slsi_dev
, mx_wlan_client
);
160 SLSI_INFO_NODEV("\n");
162 mutex_lock(&slsi_start_mutex
);
163 recovery_in_progress
= 1;
164 sdev
->recovery_status
= 1;
165 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
166 /* system error level is set in failure_notification. if this is not yet set, consider
167 * a full panic. set it to SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC
169 system_error_level
= atomic_read(&sdev
->cm_if
.reset_level
);
170 if (!system_error_level
) {
171 atomic_set(&sdev
->cm_if
.reset_level
, SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC
);
173 if (state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
) {
174 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_BLOCKED
);
175 sdev
->fail_reported
= true;
177 /* If next state is stopped, then don't signal recovery since
178 * the Android framework won't/shouldn't restart (supplicant
181 if (sdev
->recovery_next_state
!= SCSC_WIFI_CM_IF_STATE_STOPPING
) {
182 slsi_hip_block_bh(sdev
);
184 /* Stop wlan operations. Send event to registered parties */
185 mutex_unlock(&slsi_start_mutex
);
186 SLSI_INFO_NODEV("Nofity registered functions\n");
187 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_STOP
, sdev
);
188 mutex_lock(&slsi_start_mutex
);
191 SLSI_INFO_NODEV("Wi-Fi service driver not started\n");
194 mutex_unlock(&slsi_start_mutex
);
197 int slsi_check_rf_test_mode(void)
199 struct file
*fp
= NULL
;
200 #if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000
201 char *filepath
= "/data/vendor/conn/.psm.info";
203 char *filepath
= "/data/misc/conn/.psm.info";
207 fp
= filp_open(filepath
, O_RDONLY
, 0);
208 if (IS_ERR(fp
) || (!fp
)) {
209 pr_err("%s is not exist.\n", filepath
);
210 return -ENOENT
; /* -2 */
213 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
214 kernel_read(fp
, &power_val
, 1, &fp
->f_pos
);
216 kernel_read(fp
, fp
->f_pos
, &power_val
, 1);
218 /* if power_val is 0, it means rf_test mode by rf. */
219 if (power_val
== '0') {
220 pr_err("*#rf# is enabled.\n");
221 EnableRfTestMode
= 1;
223 pr_err("*#rf# is disabled.\n");
224 EnableRfTestMode
= 0;
228 filp_close(fp
, NULL
);
233 /* WLAN service driver registration
234 * ================================
236 void slsi_wlan_service_probe(struct scsc_mx_module_client
*module_client
, struct scsc_mx
*mx
, enum scsc_module_client_reason reason
)
238 struct slsi_dev
*sdev
;
240 struct scsc_service_client mx_wlan_client
;
241 #ifdef CONFIG_SCSC_LOG_COLLECTION
242 char buf
[SCSC_LOG_FAPI_VERSION_SIZE
];
245 SLSI_UNUSED_PARAMETER(module_client
);
247 SLSI_INFO_NODEV("WLAN service probe\n");
249 mutex_lock(&slsi_start_mutex
);
251 if (reason
== SCSC_MODULE_CLIENT_REASON_RECOVERY
&& !recovery_in_progress
)
254 if (reason
== SCSC_MODULE_CLIENT_REASON_RECOVERY
) {
255 SLSI_INFO_NODEV("Probe recovery\n");
257 recovery_in_progress
= 0;
258 sdev
->fail_reported
= false;
259 sdev
->recovery_status
= 0;
260 sdev
->mlme_blocked
= false;
261 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
262 mutex_unlock(&slsi_start_mutex
);
263 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_CHIP_READY
, sdev
);
264 mutex_lock(&slsi_start_mutex
);
266 complete_all(&sdev
->recovery_completed
);
268 /* Register callbacks */
269 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
270 mx_wlan_client
.failure_notification
= wlan_failure_notification
;
271 mx_wlan_client
.stop_on_failure_v2
= wlan_stop_on_failure_v2
;
272 mx_wlan_client
.failure_reset_v2
= wlan_failure_reset_v2
;
274 mx_wlan_client
.stop_on_failure
= wlan_stop_on_failure
;
275 mx_wlan_client
.failure_reset
= wlan_failure_reset
;
276 mx_wlan_client
.suspend
= wlan_suspend
;
277 mx_wlan_client
.resume
= wlan_resume
;
279 dev
= scsc_service_get_device_by_mx(mx
);
281 /* The mutex must be released at this point since the attach
282 * process may call various functions including
283 * slsi_sm_wlan_service_start and slsi_sm_wlan_service_open, which will
284 * claim the same mutex.
286 mutex_unlock(&slsi_start_mutex
);
287 sdev
= slsi_dev_attach(dev
, mx
, &mx_wlan_client
);
288 mutex_lock(&slsi_start_mutex
);
290 SLSI_ERR_NODEV("WLAN attach failed - slsi_dev_attach\n");
294 cm_ctx
.sdev
= sdev
; /* TODO: For now. */
296 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_PROBING
);
299 #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING
300 hip4_sampler_create(sdev
, mx
);
302 #ifdef CONFIG_SCSC_LOG_COLLECTION
303 memset(buf
, 0, SCSC_LOG_FAPI_VERSION_SIZE
);
304 /* Write FAPI VERSION to collector header */
305 /* IMPORTANT - Do not change the formatting as User space tooling is parsing the string
306 * to read SAP fapi versions.
308 snprintf(buf
, SCSC_LOG_FAPI_VERSION_SIZE
, "ma:%u.%u, mlme:%u.%u, debug:%u.%u, test:%u.%u",
309 FAPI_MAJOR_VERSION(FAPI_DATA_SAP_VERSION
), FAPI_MINOR_VERSION(FAPI_DATA_SAP_VERSION
),
310 FAPI_MAJOR_VERSION(FAPI_CONTROL_SAP_VERSION
), FAPI_MINOR_VERSION(FAPI_CONTROL_SAP_VERSION
),
311 FAPI_MAJOR_VERSION(FAPI_DEBUG_SAP_VERSION
), FAPI_MINOR_VERSION(FAPI_DEBUG_SAP_VERSION
),
312 FAPI_MAJOR_VERSION(FAPI_TEST_SAP_VERSION
), FAPI_MINOR_VERSION(FAPI_TEST_SAP_VERSION
));
314 scsc_log_collector_write_fapi(buf
, SCSC_LOG_FAPI_VERSION_SIZE
);
318 if (reason
!= SCSC_MODULE_CLIENT_REASON_RECOVERY
)
319 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_PROBED
);
320 atomic_set(&sdev
->cm_if
.reset_level
, 0);
322 mutex_unlock(&slsi_start_mutex
);
325 /* service_clean_up_locked expects the slsi_start_mutex mutex to be claimed when
326 * service_clean_up_locked is called.
328 static void service_clean_up_locked(struct slsi_dev
*sdev
)
330 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_REMOVING
);
331 put_device(sdev
->dev
);
333 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_REMOVED
);
335 sdev
->maxwell_core
= NULL
;
337 /* The mutex must be released at this point since the tear down
338 * process will call various functions including
339 * slsi_sm_wlan_service_stop and slsi_sm_wlan_service_close, which will
340 * claim the same mutex.
342 mutex_unlock(&slsi_start_mutex
);
343 slsi_dev_detach(sdev
);
344 mutex_lock(&slsi_start_mutex
);
347 static void slsi_wlan_service_remove(struct scsc_mx_module_client
*module_client
, struct scsc_mx
*mx
, enum scsc_module_client_reason reason
)
349 struct slsi_dev
*sdev
;
353 SLSI_UNUSED_PARAMETER(mx
);
354 SLSI_UNUSED_PARAMETER(module_client
);
358 SLSI_INFO_NODEV("no sdev\n");
362 if (reason
== SCSC_MODULE_CLIENT_REASON_RECOVERY
&& !recovery_in_progress
) {
363 SLSI_INFO_NODEV("WLAN service remove - recovery. Service not active.\n");
364 } else if (reason
== SCSC_MODULE_CLIENT_REASON_RECOVERY
&& recovery_in_progress
) {
367 SLSI_INFO_NODEV("WLAN service remove - recovery\n");
369 /* Only indicate if the next state is not stopping. The recovery
370 * handling won't have any affect if the framework is closing
373 if (sdev
->recovery_next_state
!= SCSC_WIFI_CM_IF_STATE_STOPPING
) {
374 SLSI_INFO_NODEV("Nofity registered functions\n");
375 blocking_notifier_call_chain(&slsi_wlan_notifier
, SCSC_WIFI_FAILURE_RESET
, sdev
);
377 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
378 level
= atomic_read(&sdev
->cm_if
.reset_level
);
380 if (level
== SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC
) {
381 mutex_lock(&slsi_start_mutex
);
383 * If there was a request to stop during the recovery, then do
384 * not sent a hang - just stop here. The Wi-Fi service driver is
385 * ready to be turned on again. Let the service_stop complete.
387 complete_all(&sdev
->recovery_remove_completion
);
388 if (sdev
->recovery_next_state
== SCSC_WIFI_CM_IF_STATE_STOPPING
) {
389 SLSI_INFO_NODEV("Recovery - next state stopping\n");
391 SLSI_INFO_NODEV("Calling slsi_send_hanged_vendor_event with latest_scsc_panic_code=0x%x\n",
392 latest_scsc_panic_code
);
393 if (slsi_send_hanged_vendor_event(sdev
, latest_scsc_panic_code
) < 0)
394 SLSI_ERR(sdev
, "Failed to send hang event\n");
396 /* Complete any pending ctrl signals, which will prevent
397 * the hang event from being processed.
399 complete_all(&sdev
->sig_wait
.completion
);
402 mutex_unlock(&slsi_start_mutex
);
404 r
= wait_for_completion_timeout(&sdev
->recovery_stop_completion
,
405 msecs_to_jiffies(sdev
->recovery_timeout
));
407 SLSI_INFO(sdev
, "recovery_stop_completion timeout\n");
409 mutex_lock(&slsi_start_mutex
);
410 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
411 reinit_completion(&sdev
->recovery_stop_completion
);
413 /*This is how the macro is used in the older verion.*/
414 INIT_COMPLETION(sdev
->recovery_stop_completion
);
416 mutex_unlock(&slsi_start_mutex
);
419 SLSI_INFO_NODEV("WLAN service remove\n");
421 #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING
422 hip4_sampler_destroy(sdev
, mx
);
425 mutex_lock(&slsi_start_mutex
);
426 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
427 if (state
!= SCSC_WIFI_CM_IF_STATE_STARTED
&&
428 state
!= SCSC_WIFI_CM_IF_STATE_PROBED
&&
429 state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
&&
430 state
!= SCSC_WIFI_CM_IF_STATE_BLOCKED
) {
431 mutex_unlock(&slsi_start_mutex
);
432 SLSI_INFO_NODEV("state-event error %d\n", state
);
436 service_clean_up_locked(sdev
);
437 mutex_unlock(&slsi_start_mutex
);
441 /* Block future HIP runs through the hip_switch */
442 static void slsi_hip_block_bh(struct slsi_dev
*sdev
)
444 SLSI_WARN(sdev
, "HIP state set to #SLSI_HIP_STATE_BLOCKED#\n");
445 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_BLOCKED
);
448 struct scsc_mx_module_client wlan_driver
= {
449 .name
= "WLAN driver",
450 .probe
= slsi_wlan_service_probe
,
451 .remove
= slsi_wlan_service_remove
,
454 int slsi_sm_service_driver_register(void)
456 struct slsi_cm_ctx
*ctx
= &cm_ctx
;
458 memset(ctx
, 0, sizeof(*ctx
));
459 mutex_init(&slsi_start_mutex
);
460 scsc_mx_module_register_client_module(&wlan_driver
);
465 void slsi_sm_service_driver_unregister(void)
467 scsc_mx_module_unregister_client_module(&wlan_driver
);
470 /* start/stop wlan service
471 * =======================
473 void slsi_sm_service_failed(struct slsi_dev
*sdev
, const char *reason
)
477 mutex_lock(&slsi_start_mutex
);
479 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
480 if (state
!= SCSC_WIFI_CM_IF_STATE_STARTED
&&
481 state
!= SCSC_WIFI_CM_IF_STATE_STOPPING
) {
482 mutex_unlock(&slsi_start_mutex
);
483 SLSI_INFO(sdev
, "State %d - ignoring event\n", state
);
487 /* Limit the volume of error reports to the core */
488 if (!sdev
->fail_reported
) {
489 /* This log may be scraped by test systems */
490 SLSI_ERR(sdev
, "scsc_wifibt: FATAL ERROR: %s\n", reason
);
492 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_BLOCKED
);
493 slsi_hip_block_bh(sdev
);
494 scsc_mx_service_service_failed(sdev
->service
, reason
);
495 scsc_mx_service_mif_dump_registers(sdev
->service
);
496 sdev
->fail_reported
= true;
499 mutex_unlock(&slsi_start_mutex
);
502 /* Is production test mode enabled? */
503 bool slsi_is_test_mode_enabled(void)
505 return EnableTestMode
;
508 /* Is production rf test mode enabled? */
509 bool slsi_is_rf_test_mode_enabled(void)
511 return EnableRfTestMode
;
514 #define SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT 20000
515 #define SLSI_SM_WLAN_SERVICE_RECOVERY_DISABLED_TIMEOUT 2000
517 int slsi_sm_recovery_service_stop(struct slsi_dev
*sdev
)
521 mutex_lock(&slsi_start_mutex
);
522 SLSI_INFO_NODEV("Stopping WLAN service\n");
523 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPING
);
524 err
= scsc_mx_service_stop(sdev
->service
);
525 if (err
== -EILSEQ
|| err
== -EIO
)
526 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err: %d\n", err
);
529 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
530 mutex_unlock(&slsi_start_mutex
);
534 int slsi_sm_recovery_service_close(struct slsi_dev
*sdev
)
538 mutex_lock(&slsi_start_mutex
);
539 SLSI_INFO_NODEV("Closing WLAN service\n");
540 err
= scsc_mx_service_close(sdev
->service
);
541 if (err
== -EILSEQ
|| err
== -EIO
)
542 SLSI_INFO(sdev
, "scsc_mx_service_close failed err: %d\n", err
);
545 mutex_unlock(&slsi_start_mutex
);
549 int slsi_sm_recovery_service_open(struct slsi_dev
*sdev
)
553 mutex_lock(&slsi_start_mutex
);
554 SLSI_INFO_NODEV("Open WLAN service\n");
555 sdev
->service
= scsc_mx_service_open(sdev
->maxwell_core
, SCSC_SERVICE_ID_WLAN
, &sdev
->mx_wlan_client
, &err
);
556 if (err
== -EILSEQ
|| err
== -EIO
)
557 SLSI_INFO(sdev
, "scsc_mx_service_open failed err: %d\n", err
);
560 mutex_unlock(&slsi_start_mutex
);
564 int slsi_sm_recovery_service_start(struct slsi_dev
*sdev
)
566 int err
= 0, err2
= 0;
567 struct slsi_hip4
*hip
= &sdev
->hip4_inst
;
571 mutex_lock(&slsi_start_mutex
);
572 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
574 "Recovery -- Status:%d In_Progress:%d -- cm_if_state:%d\n",
575 sdev
->recovery_status
, recovery_in_progress
, state
);
576 if (state
!= SCSC_WIFI_CM_IF_STATE_PROBED
&&
577 state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
) {
578 SLSI_INFO(sdev
, "State-event error %d\n", state
);
579 mutex_unlock(&slsi_start_mutex
);
583 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STARTING
);
584 #ifdef CONFIG_SCSC_PCIE
585 err
= scsc_mx_service_mifram_alloc(sdev
->service
, 1.5 * 1024 * 1024, &sdev
->hip4_inst
.hip_ref
, 4096);
587 err
= scsc_mx_service_mifram_alloc(sdev
->service
, 2 * 1024 * 1024, &sdev
->hip4_inst
.hip_ref
, 4096);
590 SLSI_WARN(sdev
, "scsc_mx_service_mifram_alloc failed err: %d\n", err
);
591 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
592 mutex_unlock(&slsi_start_mutex
);
596 err
= slsi_hip_start(sdev
);
598 SLSI_WARN(sdev
, "slsi_hip_start failed err: %d\n", err
);
599 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
601 mutex_unlock(&slsi_start_mutex
);
605 err
= scsc_mx_service_mif_ptr_to_addr(sdev
->service
, hip
->hip_control
, &ref
);
607 SLSI_WARN(sdev
, "scsc_mx_service_mif_ptr_to_addr failed err: %d\n", err
);
608 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
610 mutex_unlock(&slsi_start_mutex
);
615 err
= scsc_mx_service_start(sdev
->service
, ref
);
617 SLSI_WARN(sdev
, "scsc_mx_service_start failed err: %d\n", err
);
618 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
620 mutex_unlock(&slsi_start_mutex
);
623 err
= slsi_hip_setup(sdev
);
625 SLSI_WARN(sdev
, "slsi_hip_setup failed err: %d\n", err
);
626 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
627 err2
= scsc_mx_service_stop(sdev
->service
);
629 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err2: %d\n", err2
);
631 mutex_unlock(&slsi_start_mutex
);
635 /* Service has started, inform SAP versions to the registered SAPs */
636 err
= slsi_hip_sap_setup(sdev
);
638 SLSI_WARN(sdev
, "slsi_hip_sap_setup failed err: %d\n", err
);
639 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
640 err2
= scsc_mx_service_stop(sdev
->service
);
642 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err2: %d\n", err2
);
644 mutex_unlock(&slsi_start_mutex
);
647 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STARTED
);
648 mutex_unlock(&slsi_start_mutex
);
652 int slsi_sm_wlan_service_open(struct slsi_dev
*sdev
)
657 mutex_lock(&slsi_start_mutex
);
658 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
659 if (state
!= SCSC_WIFI_CM_IF_STATE_PROBED
&&
660 state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
) {
661 SLSI_INFO(sdev
, "State-event error %d\n", state
);
666 sdev
->recovery_timeout
= mxman_recovery_disabled() ? SLSI_SM_WLAN_SERVICE_RECOVERY_DISABLED_TIMEOUT
: SLSI_SM_WLAN_SERVICE_RECOVERY_COMPLETED_TIMEOUT
;
668 /* Open service - will download FW - will set MBOX0 with Starting address */
669 SLSI_INFO(sdev
, "Open WLAN service\n");
670 sdev
->service
= scsc_mx_service_open(sdev
->maxwell_core
, SCSC_SERVICE_ID_WLAN
, &sdev
->mx_wlan_client
, &err
);
671 if (!sdev
->service
) {
672 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_PROBED
);
673 SLSI_WARN(sdev
, "Service open failed\n");
679 mutex_unlock(&slsi_start_mutex
);
683 #if defined(CONFIG_SLUB_DEBUG_ON) || defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_DEBUG_RT_MUTEXES) || \
684 defined(CONFIG_DEBUG_SPINLOCK) && defined(CONFIG_DEBUG_MUTEXES) && defined(CONFIG_DEBUG_LOCK_ALLOC) || \
685 defined(CONFIG_DEBUG_LOCK_ALLOC) && defined(CONFIG_DEBUG_ATOMIC_SLEEP) && defined(CONFIG_DEBUG_LIST)
686 #define KERNEL_DEBUG_OPTIONS_ENABLED
689 int slsi_sm_wlan_service_start(struct slsi_dev
*sdev
)
691 struct slsi_hip4
*hip
= &sdev
->hip4_inst
;
697 mutex_lock(&slsi_start_mutex
);
698 state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
700 "Recovery -- Status:%d In_Progress:%d -- cm_if_state:%d\n",
701 sdev
->recovery_status
, recovery_in_progress
, state
);
702 if (state
!= SCSC_WIFI_CM_IF_STATE_PROBED
&&
703 state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
) {
704 SLSI_INFO(sdev
, "State-event error %d\n", state
);
705 mutex_unlock(&slsi_start_mutex
);
709 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STARTING
);
711 #ifdef KERNEL_DEBUG_OPTIONS_ENABLED
712 SLSI_WARN(sdev
, "Kernel config debug options are enabled. This might impact the throughput performance.\n");
715 /* Get RAM from the MIF */
716 SLSI_INFO(sdev
, "Allocate mifram\n");
718 #ifdef CONFIG_SCSC_PCIE
719 err
= scsc_mx_service_mifram_alloc(sdev
->service
, 1.5 * 1024 * 1024, &sdev
->hip4_inst
.hip_ref
, 4096);
721 err
= scsc_mx_service_mifram_alloc(sdev
->service
, 2 * 1024 * 1024, &sdev
->hip4_inst
.hip_ref
, 4096);
724 SLSI_WARN(sdev
, "scsc_mx_service_mifram_alloc failed err: %d\n", err
);
725 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
726 mutex_unlock(&slsi_start_mutex
);
730 SLSI_INFO(sdev
, "Start HIP\n");
731 err
= slsi_hip_start(sdev
);
733 SLSI_WARN(sdev
, "slsi_hip_start failed err: %d\n", err
);
734 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
736 mutex_unlock(&slsi_start_mutex
);
740 err
= scsc_mx_service_mif_ptr_to_addr(sdev
->service
, hip
->hip_control
, &ref
);
742 SLSI_WARN(sdev
, "scsc_mx_service_mif_ptr_to_addr failed err: %d\n", err
);
743 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
745 mutex_unlock(&slsi_start_mutex
);
749 SLSI_INFO(sdev
, "Starting WLAN service\n");
750 err
= scsc_mx_service_start(sdev
->service
, ref
);
752 SLSI_WARN(sdev
, "scsc_mx_service_start failed err: %d\n", err
);
753 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
755 mutex_unlock(&slsi_start_mutex
);
758 err
= slsi_hip_setup(sdev
);
760 SLSI_WARN(sdev
, "slsi_hip_setup failed err: %d\n", err
);
761 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
762 SLSI_INFO_NODEV("Stopping WLAN service\n");
763 err2
= scsc_mx_service_stop(sdev
->service
);
765 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err2: %d\n", err2
);
767 mutex_unlock(&slsi_start_mutex
);
770 /* Service has started, inform SAP versions to the registered SAPs */
771 err
= slsi_hip_sap_setup(sdev
);
773 SLSI_WARN(sdev
, "slsi_hip_sap_setup failed err: %d\n", err
);
774 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
775 SLSI_INFO_NODEV("Stopping WLAN service\n");
776 err2
= scsc_mx_service_stop(sdev
->service
);
778 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err2: %d\n", err2
);
780 mutex_unlock(&slsi_start_mutex
);
783 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STARTED
);
784 mutex_unlock(&slsi_start_mutex
);
788 static void __slsi_sm_wlan_service_stop_wait_locked(struct slsi_dev
*sdev
)
792 mutex_unlock(&slsi_start_mutex
);
793 r
= wait_for_completion_timeout(&sdev
->recovery_remove_completion
,
794 msecs_to_jiffies(sdev
->recovery_timeout
));
796 SLSI_INFO(sdev
, "recovery_remove_completion timeout\n");
798 mutex_lock(&slsi_start_mutex
);
799 sdev
->recovery_next_state
= SCSC_WIFI_CM_IF_STATE_STOPPED
;
801 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
802 reinit_completion(&sdev
->recovery_remove_completion
);
804 /*This is how the macro is used in the older verion.*/
805 INIT_COMPLETION(sdev
->recovery_remove_completion
);
809 void slsi_sm_wlan_service_stop(struct slsi_dev
*sdev
)
814 mutex_lock(&slsi_start_mutex
);
815 cm_if_state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
817 "Recovery -- Status:%d In_Progress:%d -- cm_if_state:%d\n",
818 sdev
->recovery_status
, recovery_in_progress
, cm_if_state
);
820 if (cm_if_state
== SCSC_WIFI_CM_IF_STATE_BLOCKED
) {
821 __slsi_sm_wlan_service_stop_wait_locked(sdev
);
823 /* If the wait hasn't timed out, the recovery remove completion
824 * will have completed properly and the cm_if_state will be
825 * set to stopped here. If the probe hasn't fired for some reason
826 * try and do a service_stop regardless, since that's all we can
827 * do in this situation; hence skip the state check.
829 goto skip_state_check
;
832 if (cm_if_state
!= SCSC_WIFI_CM_IF_STATE_STARTED
&&
833 cm_if_state
!= SCSC_WIFI_CM_IF_STATE_REMOVED
&&
834 cm_if_state
!= SCSC_WIFI_CM_IF_STATE_PROBED
) {
835 SLSI_INFO(sdev
, "Service not started or incorrect state %d\n",
841 * Note that the SCSC_WIFI_CM_IF_STATE_STOPPING state will inhibit
842 * auto-recovery mechanism, so be careful not to abuse it: as an
843 * example if panic happens on start or stop we don't want to
844 * un-necessarily pass by STOPPING in order to have a successful
845 * recovery in such a situation.
847 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPING
);
849 SLSI_INFO_NODEV("Stopping WLAN service\n");
850 err
= scsc_mx_service_stop(sdev
->service
);
851 if (err
== -EILSEQ
) {
852 /* scsc_mx_service_stop failed since there's a recovery in
853 * progress, so just wait for it to complete and try again.
855 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err: %d\n", err
);
856 __slsi_sm_wlan_service_stop_wait_locked(sdev
);
857 goto skip_state_check
;
858 } else if (err
== -EIO
) {
861 SLSI_INFO(sdev
, "scsc_mx_service_stop failed err: %d\n", err
);
863 /* scsc_mx_service_stop since there was no respons from firmware
864 * to the stop request. Generate a host initiated panic to reset
865 * the chip and wait for it to complete.
867 sdev
->recovery_next_state
= SCSC_WIFI_CM_IF_STATE_STOPPING
;
868 snprintf(reason
, sizeof(reason
), "WLAN scsc_mx_service_stop failed");
870 mutex_unlock(&slsi_start_mutex
);
871 slsi_sm_service_failed(sdev
, reason
);
872 mutex_lock(&slsi_start_mutex
);
874 __slsi_sm_wlan_service_stop_wait_locked(sdev
);
875 } else if (err
== -EPERM
) {
876 /* Special case when recovery is disabled, otherwise the driver
877 * will wait forever for recovery that never comes
879 SLSI_INFO(sdev
, "refused due to previous failure, recovery is disabled: %d\n", err
);
880 } else if (err
!= 0) {
881 SLSI_INFO(sdev
, "scsc_mx_service_stop failed, unknown err: %d\n", err
);
884 atomic_set(&sdev
->cm_if
.cm_if_state
, SCSC_WIFI_CM_IF_STATE_STOPPED
);
886 mutex_unlock(&slsi_start_mutex
);
889 #define SLSI_SM_WLAN_SERVICE_CLOSE_RETRY 60
890 void slsi_sm_wlan_service_close(struct slsi_dev
*sdev
)
894 mutex_lock(&slsi_start_mutex
);
895 cm_if_state
= atomic_read(&sdev
->cm_if
.cm_if_state
);
896 if (cm_if_state
!= SCSC_WIFI_CM_IF_STATE_STOPPED
) {
897 SLSI_INFO(sdev
, "Service not stopped. cm_if_state = %d\n", cm_if_state
);
900 * Close the service if failure has occurred after service has successfully opened
901 * but before service has attempted to start
903 if (cm_if_state
== SCSC_WIFI_CM_IF_STATE_PROBED
) {
904 SLSI_INFO_NODEV("Closing WLAN service on error\n");
905 r
= scsc_mx_service_close(sdev
->service
);
910 SLSI_INFO_NODEV("Closing WLAN service\n");
911 scsc_mx_service_mifram_free(sdev
->service
, sdev
->hip4_inst
.hip_ref
);
913 r
= scsc_mx_service_close(sdev
->service
);
918 * Error handling in progress - try and close again later.
919 * The service close call shall remain blocked until close
920 * service is successful. Try up to 30 seconds.
922 for (retry_counter
= 0;
923 SLSI_SM_WLAN_SERVICE_CLOSE_RETRY
> retry_counter
;
926 r
= scsc_mx_service_close(sdev
->service
);
928 SLSI_INFO(sdev
, "scsc_mx_service_close closed after %d attempts\n",
934 if (retry_counter
+ 1 == SLSI_SM_WLAN_SERVICE_CLOSE_RETRY
)
935 SLSI_ERR(sdev
, "scsc_mx_service_close failed %d times\n",
936 SLSI_SM_WLAN_SERVICE_CLOSE_RETRY
);
937 } else if (r
== -EPERM
) {
938 SLSI_ERR(sdev
, "scsc_mx_service_close - recovery is disabled (%d)\n", r
);
941 if (recovery_in_progress
)
942 complete_all(&sdev
->recovery_stop_completion
);
944 mutex_unlock(&slsi_start_mutex
);