1 /****************************************************************************
3 * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
13 #include "cfg80211_ops.h"
17 #include "nl80211_vendor.h"
24 #ifdef CONFIG_SCSC_WLAN_KIC_OPS
28 char *slsi_mib_file
= "wlan.hcf";
29 module_param_named(mib_file
, slsi_mib_file
, charp
, S_IRUGO
| S_IWUSR
);
30 MODULE_PARM_DESC(mib_file
, "mib data filename");
32 char *slsi_mib_file2
= "wlan_sw.hcf";
33 module_param_named(mib_file2
, slsi_mib_file2
, charp
, S_IRUGO
| S_IWUSR
);
34 MODULE_PARM_DESC(mib_file2
, "sw mib data filename");
36 static char *local_mib_file
= "localmib.hcf";
37 module_param(local_mib_file
, charp
, S_IRUGO
| S_IWUSR
);
38 MODULE_PARM_DESC(local_mib_file
, "local mib data filename (Optional extra mib values)");
40 static char *maddr_file
= "mac.txt";
41 module_param(maddr_file
, charp
, S_IRUGO
| S_IWUSR
);
42 MODULE_PARM_DESC(maddr_file
, "mac address filename");
44 static bool term_udi_users
= true;
45 module_param(term_udi_users
, bool, S_IRUGO
| S_IWUSR
);
46 MODULE_PARM_DESC(term_udi_users
, "Try to terminate UDI user space users (applications) connected on the cdev (0, 1)");
48 static int sig_wait_cfm_timeout
= 6000;
49 module_param(sig_wait_cfm_timeout
, int, S_IRUGO
| S_IWUSR
);
50 MODULE_PARM_DESC(sig_wait_cfm_timeout
, "Signal wait timeout in milliseconds (default: 3000)");
52 static bool lls_disabled
;
53 module_param(lls_disabled
, bool, S_IRUGO
| S_IWUSR
);
54 MODULE_PARM_DESC(lls_disabled
, "Disable LLS: to disable LLS set 1");
56 static bool gscan_disabled
= 0;
57 module_param(gscan_disabled
, bool, S_IRUGO
| S_IWUSR
);
58 MODULE_PARM_DESC(gscan_disabled
, "Disable gscan: to disable gscan set 1");
60 static bool llslogs_disabled
;
61 module_param(llslogs_disabled
, bool, S_IRUGO
| S_IWUSR
);
62 MODULE_PARM_DESC(llslogs_disabled
, "Disable llslogs: to disable llslogs set 1");
64 static bool epno_disabled
;
65 module_param(epno_disabled
, bool, S_IRUGO
| S_IWUSR
);
66 MODULE_PARM_DESC(epno_disabled
, "Disable ePNO: to disable ePNO set 1.\nNote: for ePNO to work gscan should be enabled");
68 static bool vo_vi_block_ack_disabled
;
69 module_param(vo_vi_block_ack_disabled
, bool, S_IRUGO
| S_IWUSR
);
70 MODULE_PARM_DESC(vo_vi_block_ack_disabled
, "Disable VO VI Block Ack logic added for WMM AC Cert : 5.1.4");
72 static int max_scan_result_count
= 200;
73 module_param(max_scan_result_count
, int, S_IRUGO
| S_IWUSR
);
74 MODULE_PARM_DESC(max_scan_result_count
, "Max scan results to be reported");
75 static bool rtt_disabled
= 1;
76 module_param(rtt_disabled
, bool, S_IRUGO
| S_IWUSR
);
77 MODULE_PARM_DESC(rtt_disabled
, "Disable rtt: to disable rtt set 1");
79 static bool nan_disabled
;
80 module_param(nan_disabled
, bool, S_IRUGO
| S_IWUSR
);
81 MODULE_PARM_DESC(nan_disabled
, "Disable NAN: to disable NAN set 1.");
83 bool slsi_dev_gscan_supported(void)
85 return !gscan_disabled
;
88 bool slsi_dev_rtt_supported(void)
93 bool slsi_dev_llslogs_supported(void)
95 return !llslogs_disabled
;
98 bool slsi_dev_lls_supported(void)
100 return !lls_disabled
;
103 bool slsi_dev_epno_supported(void)
105 return !epno_disabled
;
108 bool slsi_dev_vo_vi_block_ack(void)
110 return vo_vi_block_ack_disabled
;
113 int slsi_dev_get_scan_result_count(void)
115 return max_scan_result_count
;
118 int slsi_dev_nan_supported(struct slsi_dev
*sdev
)
120 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
122 return sdev
->nan_enabled
&& !nan_disabled
;
129 static int slsi_dev_inetaddr_changed(struct notifier_block
*nb
, unsigned long data
, void *arg
)
131 struct slsi_dev
*sdev
= container_of(nb
, struct slsi_dev
, inetaddr_notifier
);
132 struct in_ifaddr
*ifa
= arg
;
133 struct net_device
*dev
= ifa
->ifa_dev
->dev
;
134 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
135 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
140 if (wdev
->wiphy
!= sdev
->wiphy
)
143 if (data
== NETDEV_DOWN
) {
144 SLSI_NET_DBG2(dev
, SLSI_NETDEV
, "Returning 0 for NETDEV_DOWN event\n");
148 SLSI_NET_INFO(dev
, "IP: %pI4\n", &ifa
->ifa_address
);
149 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
150 #if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID
151 if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif
) && wake_lock_active(&sdev
->wlan_wl_roam
)) {
152 SLSI_NET_DBG2(dev
, SLSI_NETDEV
, "Releasing the roaming wakelock\n");
153 wake_unlock(&sdev
->wlan_wl_roam
);
154 /* If upper layers included wps ie in connect but the actually
155 * connection is not for wps, reset the wps flag.
157 if (ndev_vif
->sta
.is_wps
) {
158 SLSI_NET_DBG1(dev
, SLSI_NETDEV
,
159 "is_wps set but not wps connection.\n");
160 ndev_vif
->sta
.is_wps
= false;
164 slsi_ip_address_changed(sdev
, dev
, ifa
->ifa_address
);
165 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
169 #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6
170 static int slsi_dev_inet6addr_changed(struct notifier_block
*nb
, unsigned long data
, void *arg
)
172 struct slsi_dev
*sdev
= container_of(nb
, struct slsi_dev
, inet6addr_notifier
);
173 struct inet6_ifaddr
*ifa
= arg
;
174 struct net_device
*dev
= ifa
->idev
->dev
;
175 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
176 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
178 (void)data
; /* unused */
183 if (wdev
->wiphy
!= sdev
->wiphy
)
186 SLSI_NET_INFO(dev
, "IPv6: %pI6\n", &ifa
->addr
.s6_addr
);
188 slsi_spinlock_lock(&ndev_vif
->ipv6addr_lock
);
189 memcpy(&ndev_vif
->ipv6address
, &ifa
->addr
, sizeof(struct in6_addr
));
190 slsi_spinlock_unlock(&ndev_vif
->ipv6addr_lock
);
196 void slsi_regd_init(struct slsi_dev
*sdev
)
198 struct ieee80211_regdomain
*slsi_world_regdom_custom
= sdev
->device_config
.domain_info
.regdomain
;
199 struct ieee80211_reg_rule reg_rules
[] = {
201 REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0),
202 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
203 /* Channel 12 - 13 NO_IR*/
204 REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20, NL80211_RRF_NO_IR
),
206 /* Channel 36 - 48 */
207 REG_RULE(5180 - 10, 5240 + 10, 80, 0, 20, 0),
208 /* Channel 52 - 64 */
209 REG_RULE(5260 - 10, 5320 + 10, 80, 0, 20, NL80211_RRF_DFS
),
210 /* Channel 100 - 140 */
211 REG_RULE(5500 - 10, 5700 + 10, 80, 0, 20, NL80211_RRF_DFS
),
212 /* Channel 149 - 165 */
213 REG_RULE(5745 - 10, 5825 + 10, 80, 0, 20, 0),
218 SLSI_DBG1_NODEV(SLSI_INIT_DEINIT
, "regulatory init\n");
219 slsi_world_regdom_custom
->n_reg_rules
= 6;
220 for (i
= 0; i
< slsi_world_regdom_custom
->n_reg_rules
; i
++)
221 slsi_world_regdom_custom
->reg_rules
[i
] = reg_rules
[i
];
223 /* Country code '00' indicates world regulatory domain */
224 slsi_world_regdom_custom
->alpha2
[0] = '0';
225 slsi_world_regdom_custom
->alpha2
[1] = '0';
227 wiphy_apply_custom_regulatory(sdev
->wiphy
, slsi_world_regdom_custom
);
230 struct slsi_dev
*slsi_dev_attach(struct device
*dev
, struct scsc_mx
*core
, struct scsc_service_client
*mx_wlan_client
)
232 struct slsi_dev
*sdev
;
235 SLSI_DBG1_NODEV(SLSI_INIT_DEINIT
, "Add Device\n");
237 sdev
= slsi_cfg80211_new(dev
);
239 SLSI_ERR_NODEV("No sdev\n");
243 sdev
->mlme_blocked
= false;
245 SLSI_MUTEX_INIT(sdev
->netdev_add_remove_mutex
);
246 mutex_init(&sdev
->netdev_remove_mutex
);
247 SLSI_MUTEX_INIT(sdev
->start_stop_mutex
);
248 SLSI_MUTEX_INIT(sdev
->device_config_mutex
);
249 SLSI_MUTEX_INIT(sdev
->logger_mutex
);
252 sdev
->maxwell_core
= core
;
253 memcpy(&sdev
->mx_wlan_client
, mx_wlan_client
, sizeof(struct scsc_service_client
));
255 sdev
->fail_reported
= false;
256 sdev
->p2p_certif
= false;
257 sdev
->allow_switch_40_mhz
= true;
258 sdev
->allow_switch_80_mhz
= true;
259 sdev
->mib
[0].mib_file_name
= slsi_mib_file
;
260 sdev
->mib
[1].mib_file_name
= slsi_mib_file2
;
261 sdev
->local_mib
.mib_file_name
= local_mib_file
;
262 sdev
->maddr_file_name
= maddr_file
;
263 sdev
->device_config
.qos_info
= -1;
264 sdev
->acs_channel_switched
= false;
265 memset(&sdev
->chip_info_mib
, 0xFF, sizeof(struct slsi_chip_info_mib
));
267 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
268 sdev
->num_5g_restricted_channels
= 0;
271 #ifdef CONFIG_SCSC_WLAN_WES_NCHO
272 sdev
->device_config
.okc_mode
= 0;
273 sdev
->device_config
.wes_mode
= 0;
274 sdev
->device_config
.roam_scan_mode
= 0;
277 slsi_log_clients_init(sdev
);
279 slsi_wakelock_init(&sdev
->wlan_wl
, "wlan");
280 slsi_wakelock_init(&sdev
->wlan_wl_mlme
, "wlan_mlme");
281 slsi_wakelock_init(&sdev
->wlan_wl_ma
, "wlan_ma");
282 #if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID
283 wake_lock_init(&sdev
->wlan_wl_roam
, WAKE_LOCK_SUSPEND
, "wlan_roam");
285 sdev
->recovery_next_state
= 0;
286 init_completion(&sdev
->recovery_remove_completion
);
287 init_completion(&sdev
->recovery_stop_completion
);
288 init_completion(&sdev
->recovery_completed
);
289 sdev
->recovery_status
= 0;
291 sdev
->term_udi_users
= &term_udi_users
;
292 sdev
->sig_wait_cfm_timeout
= &sig_wait_cfm_timeout
;
293 slsi_sig_send_init(&sdev
->sig_wait
);
295 for (i
= 0; i
< SLSI_LLS_AC_MAX
; i
++)
296 atomic_set(&sdev
->tx_host_tag
[i
], ((1 << 2) | i
));
298 if (slsi_skb_work_init(sdev
, NULL
, &sdev
->rx_dbg_sap
, "slsi_wlan_rx_dbg_sap", slsi_rx_dbg_sap_work
) != 0)
301 if (slsi_netif_init(sdev
) != 0) {
302 SLSI_ERR(sdev
, "Can not create the network interface\n");
303 goto err_ctrl_wq_init
;
306 if (slsi_hip_init(sdev
, dev
) != 0) {
307 SLSI_ERR(sdev
, "slsi_hip_init() Failed\n");
311 if (slsi_udi_node_init(sdev
, dev
) != 0) {
312 SLSI_ERR(sdev
, "failed to init UDI\n");
316 slsi_create_proc_dir(sdev
);
317 slsi_traffic_mon_clients_init(sdev
);
319 /* update regulatory domain */
320 slsi_regd_init(sdev
);
322 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
323 slsi_nl80211_vendor_init(sdev
);
326 if (slsi_cfg80211_register(sdev
) != 0) {
327 SLSI_ERR(sdev
, "failed to register with cfg80211\n");
328 goto err_udi_proc_init
;
331 #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6
332 sdev
->inet6addr_notifier
.notifier_call
= slsi_dev_inet6addr_changed
;
333 if (register_inet6addr_notifier(&sdev
->inet6addr_notifier
) != 0) {
334 SLSI_ERR(sdev
, "failed to register inet6addr_notifier\n");
335 goto err_cfg80211_registered
;
339 sdev
->inetaddr_notifier
.notifier_call
= slsi_dev_inetaddr_changed
;
340 if (register_inetaddr_notifier(&sdev
->inetaddr_notifier
) != 0) {
341 SLSI_ERR(sdev
, "failed to register inetaddr_notifier\n");
342 #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6
343 unregister_inet6addr_notifier(&sdev
->inet6addr_notifier
);
345 goto err_cfg80211_registered
;
349 slsi_init_netdev_mac_addr(sdev
);
351 slsi_rx_ba_init(sdev
);
353 if (slsi_netif_register(sdev
, sdev
->netdev
[SLSI_NET_INDEX_WLAN
]) != 0) {
354 SLSI_ERR(sdev
, "failed to register with wlan netdev\n");
355 goto err_inetaddr_registered
;
357 #ifdef CONFIG_SCSC_WLAN_STA_ONLY
358 SLSI_ERR(sdev
, "CONFIG_SCSC_WLAN_STA_ONLY: not registering p2p netdev\n");
360 if (slsi_netif_register(sdev
, sdev
->netdev
[SLSI_NET_INDEX_P2P
]) != 0) {
361 SLSI_ERR(sdev
, "failed to register with p2p netdev\n");
362 goto err_wlan_registered
;
364 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
365 #if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
366 if (slsi_netif_register(sdev
, sdev
->netdev
[SLSI_NET_INDEX_P2PX_SWLAN
]) != 0) {
367 SLSI_ERR(sdev
, "failed to register with p2px_wlan1 netdev\n");
368 goto err_p2p_registered
;
370 rcu_assign_pointer(sdev
->netdev_ap
, sdev
->netdev
[SLSI_NET_INDEX_P2PX_SWLAN
]);
373 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
374 if (slsi_netif_register(sdev
, sdev
->netdev
[SLSI_NET_INDEX_NAN
]) != 0) {
375 SLSI_ERR(sdev
, "failed to register with NAN netdev\n");
376 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
377 #if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
378 goto err_p2px_wlan_registered
;
380 goto err_p2p_registered
;
383 goto err_p2p_registered
;
388 #ifdef CONFIG_SCSC_WLAN_KIC_OPS
389 if (wifi_kic_register(sdev
) < 0)
390 SLSI_ERR(sdev
, "failed to register Wi-Fi KIC ops\n");
392 #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER
393 sdev
->enhanced_pkt_filter_enabled
= true;
395 sdev
->device_state
= SLSI_DEVICE_STATE_STOPPED
;
396 sdev
->current_tspec_id
= -1;
397 sdev
->tspec_error_code
= -1;
399 /* Driver workqueue used to queue work in different modes (STA/P2P/HS2) */
400 sdev
->device_wq
= alloc_ordered_workqueue("slsi_wlan_wq", 0);
401 if (!sdev
->device_wq
) {
402 SLSI_ERR(sdev
, "Cannot allocate workqueue\n");
403 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
404 goto err_nan_registered
;
406 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
407 #if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
408 goto err_p2px_wlan_registered
;
410 goto err_p2p_registered
;
413 goto err_p2p_registered
;
417 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
418 INIT_WORK(&sdev
->recovery_work
, slsi_subsystem_reset
);
422 #if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
424 slsi_netif_remove(sdev
, sdev
->netdev
[SLSI_NET_INDEX_NAN
]);
427 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
428 #if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
429 err_p2px_wlan_registered
:
430 slsi_netif_remove(sdev
, sdev
->netdev
[SLSI_NET_INDEX_P2PX_SWLAN
]);
431 rcu_assign_pointer(sdev
->netdev_ap
, NULL
);
436 slsi_netif_remove(sdev
, sdev
->netdev
[SLSI_NET_INDEX_P2P
]);
439 slsi_netif_remove(sdev
, sdev
->netdev
[SLSI_NET_INDEX_WLAN
]);
441 err_inetaddr_registered
:
442 unregister_inetaddr_notifier(&sdev
->inetaddr_notifier
);
443 #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6
444 unregister_inet6addr_notifier(&sdev
->inet6addr_notifier
);
447 err_cfg80211_registered
:
448 slsi_cfg80211_unregister(sdev
);
451 slsi_traffic_mon_clients_deinit(sdev
);
452 slsi_remove_proc_dir(sdev
);
453 slsi_udi_node_deinit(sdev
);
456 slsi_hip_deinit(sdev
);
459 slsi_netif_deinit(sdev
);
462 slsi_skb_work_deinit(&sdev
->rx_dbg_sap
);
465 slsi_wakelock_exit(&sdev
->wlan_wl
);
466 slsi_wakelock_exit(&sdev
->wlan_wl_mlme
);
467 slsi_wakelock_exit(&sdev
->wlan_wl_ma
);
468 #if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID
469 wake_lock_destroy(&sdev
->wlan_wl_roam
);
471 slsi_cfg80211_free(sdev
);
475 void slsi_dev_detach(struct slsi_dev
*sdev
)
477 SLSI_DBG1(sdev
, SLSI_INIT_DEINIT
, "Remove Device\n");
481 #ifdef CONFIG_SCSC_WLAN_KIC_OPS
482 wifi_kic_unregister();
484 complete_all(&sdev
->sig_wait
.completion
);
485 complete_all(&sdev
->recovery_remove_completion
);
486 complete_all(&sdev
->recovery_stop_completion
);
487 complete_all(&sdev
->recovery_completed
);
489 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Unregister inetaddr_notifier\n");
490 unregister_inetaddr_notifier(&sdev
->inetaddr_notifier
);
492 #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6
493 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Unregister inet6addr_notifier\n");
494 unregister_inet6addr_notifier(&sdev
->inet6addr_notifier
);
497 WARN_ON(!sdev
->device_wq
);
499 flush_workqueue(sdev
->device_wq
);
501 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
502 slsi_nl80211_vendor_deinit(sdev
);
505 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Unregister netif\n");
506 slsi_netif_remove_all(sdev
);
508 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Unregister cfg80211\n");
509 slsi_cfg80211_unregister(sdev
);
511 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Remove proc entries\n");
512 slsi_remove_proc_dir(sdev
);
514 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "De-initialise the Traffic monitor\n");
515 slsi_traffic_mon_clients_deinit(sdev
);
517 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "De-initialise the UDI\n");
518 slsi_log_clients_terminate(sdev
);
519 slsi_udi_node_deinit(sdev
);
521 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "De-initialise Hip\n");
522 slsi_hip_deinit(sdev
);
524 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "De-initialise netif\n");
525 slsi_netif_deinit(sdev
);
527 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "De-initialise Regulatory\n");
528 slsi_regd_deinit(sdev
);
530 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Stop Work Queues\n");
531 slsi_skb_work_deinit(&sdev
->rx_dbg_sap
);
533 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Clean up wakelock\n");
534 slsi_wakelock_exit(&sdev
->wlan_wl
);
535 slsi_wakelock_exit(&sdev
->wlan_wl_mlme
);
536 slsi_wakelock_exit(&sdev
->wlan_wl_ma
);
537 #if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID
538 wake_lock_destroy(&sdev
->wlan_wl_roam
);
541 SLSI_DBG2(sdev
, SLSI_INIT_DEINIT
, "Free cfg80211\n");
542 slsi_cfg80211_free(sdev
);
544 slsi_dbg_track_skb_report();
545 slsi_dbg_track_skb_reset();
548 int __init
slsi_dev_load(void)
550 SLSI_INFO_NODEV("Loading Maxwell Wi-Fi driver\n");
552 slsi_dbg_track_skb_init();
555 SLSI_INFO_NODEV("Failed to init udi - continuing\n");
557 if (slsi_sm_service_driver_register())
558 SLSI_INFO_NODEV("slsi_sm_service_driver_register failed - continuing\n");
566 /* Always create devnode if TW Android P on */
567 #if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000
568 slsi_create_sysfs_macaddr();
570 SLSI_INFO_NODEV("--- Maxwell Wi-Fi driver loaded successfully ---\n");
574 void __exit
slsi_dev_unload(void)
576 SLSI_INFO_NODEV("Unloading Maxwell Wi-Fi driver\n");
578 #if defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000
579 slsi_destroy_sysfs_macaddr();
581 /* Unregister SAPs */
587 slsi_sm_service_driver_unregister();
591 SLSI_INFO_NODEV("--- Maxwell Wi-Fi driver unloaded successfully ---\n");
594 module_init(slsi_dev_load
);
595 module_exit(slsi_dev_unload
);
597 MODULE_DESCRIPTION("mx140 Wi-Fi Driver");
598 MODULE_AUTHOR("SLSI");
599 MODULE_LICENSE("GPL and additional rights");