Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 1 | /* |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 2 | * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 3 | * |
| 4 | * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| 5 | * |
| 6 | * |
| 7 | * Permission to use, copy, modify, and/or distribute this software for |
| 8 | * any purpose with or without fee is hereby granted, provided that the |
| 9 | * above copyright notice and this permission notice appear in all |
| 10 | * copies. |
| 11 | * |
| 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| 13 | * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| 14 | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| 15 | * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| 16 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| 17 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| 18 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 19 | * PERFORMANCE OF THIS SOFTWARE. |
| 20 | */ |
| 21 | |
| 22 | /* |
| 23 | * This file was originally distributed by Qualcomm Atheros, Inc. |
| 24 | * under proprietary terms before Copyright ownership was assigned |
| 25 | * to the Linux Foundation. |
| 26 | */ |
| 27 | |
Jeff Johnson | bd561a9 | 2016-01-07 18:31:35 -0800 | [diff] [blame] | 28 | /* denote that this file does not allow legacy hddLog */ |
| 29 | #define HDD_DISALLOW_LEGACY_HDDLOG 1 |
| 30 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 31 | #include <linux/platform_device.h> |
| 32 | #include <linux/pci.h> |
| 33 | #ifdef HIF_PCI |
| 34 | #ifdef CONFIG_CNSS |
| 35 | #include <net/cnss.h> |
| 36 | #endif /* CONFIG_CNSS */ |
| 37 | #else |
| 38 | #include <soc/qcom/icnss.h> |
| 39 | #endif /* HIF_PCI */ |
| 40 | #include "cds_api.h" |
Anurag Chouhan | ce0dc99 | 2016-02-16 18:18:03 +0530 | [diff] [blame] | 41 | #include "qdf_status.h" |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 42 | #include "cdf_lock.h" |
| 43 | #include "cds_sched.h" |
| 44 | #include "osdep.h" |
| 45 | #include "hif.h" |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 46 | #include "htc.h" |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 47 | #include "epping_main.h" |
| 48 | #include "wlan_hdd_main.h" |
| 49 | #include "wlan_hdd_power.h" |
| 50 | #include "wlan_logging_sock_svc.h" |
| 51 | #include "wma_api.h" |
| 52 | #include "wlan_hdd_napi.h" |
Chandrasekaran, Manishekar | 0d814c7 | 2015-11-05 10:42:48 +0530 | [diff] [blame] | 53 | #include "cds_concurrency.h" |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 54 | #include "qwlan_version.h" |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 55 | #include "bmi.h" |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 56 | |
| 57 | #ifdef MODULE |
| 58 | #define WLAN_MODULE_NAME module_name(THIS_MODULE) |
| 59 | #else |
| 60 | #define WLAN_MODULE_NAME "wlan" |
| 61 | #endif |
| 62 | |
| 63 | #ifdef HIF_PCI |
| 64 | #ifdef CONFIG_CNSS |
| 65 | #define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \ |
| 66 | cnss_wlan_register_driver(wlan_drv_ops) |
| 67 | #define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \ |
| 68 | cnss_wlan_unregister_driver(wlan_drv_ops) |
| 69 | #else |
| 70 | #define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \ |
| 71 | pci_register_driver(wlan_drv_ops) |
| 72 | #define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \ |
| 73 | pci_unregister_driver(wlan_drv_ops) |
| 74 | #endif /* CONFIG_CNSS */ |
| 75 | #else |
| 76 | #define WLAN_HDD_REGISTER_DRIVER(wlan_drv_ops) \ |
| 77 | icnss_register_driver(wlan_drv_ops) |
| 78 | #define WLAN_HDD_UNREGISTER_DRIVER(wlan_drv_ops) \ |
| 79 | icnss_unregister_driver(wlan_drv_ops) |
| 80 | #endif /* HIF_PCI */ |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 81 | #define DISABLE_KRAIT_IDLE_PS_VAL 1 |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 82 | |
| 83 | /* |
| 84 | * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at |
| 85 | * a time, and wait for the completion interrupt to start the next transfer. |
| 86 | * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS). |
| 87 | * The delay incurred for resuming from IDLE/SA PS is huge during driver load. |
| 88 | * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency. |
| 89 | */ |
| 90 | #ifdef CONFIG_CNSS |
| 91 | static inline void hdd_request_pm_qos(int val) |
| 92 | { |
| 93 | cnss_request_pm_qos(val); |
| 94 | } |
| 95 | |
| 96 | static inline void hdd_remove_pm_qos(void) |
| 97 | { |
| 98 | cnss_remove_pm_qos(); |
| 99 | } |
| 100 | #else |
| 101 | static inline void hdd_request_pm_qos(int val) |
| 102 | { |
| 103 | } |
| 104 | |
| 105 | static inline void hdd_remove_pm_qos(void) |
| 106 | { |
| 107 | } |
| 108 | #endif |
| 109 | |
| 110 | /** |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 111 | * hdd_set_recovery_in_progress() - API to set recovery in progress |
| 112 | * @data: Context |
| 113 | * @val: Value to set |
| 114 | * |
| 115 | * Return: None |
| 116 | */ |
| 117 | static void hdd_set_recovery_in_progress(void *data, uint8_t val) |
| 118 | { |
| 119 | cds_set_recovery_in_progress(val); |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * hdd_is_driver_unloading() - API to query if driver is unloading |
| 124 | * @data: Private Data |
| 125 | * |
| 126 | * Return: True/False |
| 127 | */ |
| 128 | static bool hdd_is_driver_unloading(void *data) |
| 129 | { |
| 130 | return cds_is_driver_unloading(); |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * hdd_is_load_or_unload_in_progress() - API to query if driver is |
| 135 | * loading/unloading |
| 136 | * @data: Private Data |
| 137 | * |
| 138 | * Return: bool |
| 139 | */ |
| 140 | static bool hdd_is_load_or_unload_in_progress(void *data) |
| 141 | { |
| 142 | return cds_is_load_or_unload_in_progress(); |
| 143 | } |
| 144 | |
| 145 | /** |
| 146 | * hdd_is_recovery_in_prgress() - API to query if recovery in progress |
| 147 | * @data: Private Data |
| 148 | * |
| 149 | * Return: bool |
| 150 | */ |
| 151 | static bool hdd_is_recovery_in_prgress(void *data) |
| 152 | { |
| 153 | return cds_is_driver_recovering(); |
| 154 | } |
| 155 | |
| 156 | /** |
| 157 | * hdd_hif_init_cds_callbacks() - API to initialize HIF callbacks |
| 158 | * @data: Private Data |
| 159 | * @cbk: callbacks |
| 160 | * |
| 161 | * HIF should be independent of CDS calls. Pass CDS Callbacks to HIF, HIF will |
| 162 | * call the callbacks. |
| 163 | * |
| 164 | * Return: void |
| 165 | */ |
| 166 | static void hdd_hif_init_cds_callbacks(void *data, struct hif_callbacks *cbk) |
| 167 | { |
| 168 | cbk->context = data; |
| 169 | cbk->set_recovery_in_progress = hdd_set_recovery_in_progress; |
| 170 | cbk->get_monotonic_boottime = cds_get_monotonic_boottime; |
| 171 | cbk->is_recovery_in_progress = hdd_is_recovery_in_prgress; |
| 172 | cbk->is_load_unload_in_progress = hdd_is_load_or_unload_in_progress; |
| 173 | cbk->is_driver_unloading = hdd_is_driver_unloading; |
| 174 | } |
| 175 | |
| 176 | /** |
| 177 | * hdd_init_cds_hif_context() - API to set CDS HIF Context |
| 178 | * @hif: HIF Context |
| 179 | * |
| 180 | * Return: success/failure |
| 181 | */ |
| 182 | static int hdd_init_cds_hif_context(void *hif) |
| 183 | { |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 184 | QDF_STATUS status; |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 185 | |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 186 | status = cds_set_context(QDF_MODULE_ID_HIF, hif); |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 187 | |
| 188 | if (status) |
| 189 | return -ENOENT; |
| 190 | |
| 191 | return 0; |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * hdd_deinit_cds_hif_context() - API to clear CDS HIF COntext |
| 196 | * |
| 197 | * Return: None |
| 198 | */ |
| 199 | static void hdd_deinit_cds_hif_context(void) |
| 200 | { |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 201 | QDF_STATUS status; |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 202 | |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 203 | status = cds_set_context(QDF_MODULE_ID_HIF, NULL); |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 204 | |
| 205 | if (status) |
| 206 | hdd_err("Failed to reset CDS HIF Context"); |
| 207 | |
| 208 | return; |
| 209 | } |
| 210 | |
| 211 | /** |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 212 | * hdd_hif_open() - HIF open helper |
| 213 | * @dev: wlan device structure |
| 214 | * @bdev: bus device structure |
| 215 | * @bid: bus identifier for shared busses |
| 216 | * @bus_type: underlying bus type |
| 217 | * @reinit: true if we are reinitializing the driver during recovery phase |
| 218 | * |
| 219 | * This function brings-up HIF layer during load/recovery phase. |
| 220 | * |
| 221 | * Return: 0 on success and errno on failure. |
| 222 | */ |
| 223 | static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid, |
| 224 | enum ath_hal_bus_type bus_type, bool reinit) |
| 225 | { |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 226 | QDF_STATUS status; |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 227 | int ret = 0; |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 228 | struct hif_opaque_softc *hif_ctx; |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 229 | cdf_device_t cdf_ctx = cds_get_context(CDF_MODULE_ID_CDF_DEVICE); |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 230 | struct hif_callbacks cbk; |
| 231 | uint32_t mode = cds_get_conparam(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 232 | |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 233 | hdd_hif_init_cds_callbacks(dev, &cbk); |
| 234 | |
| 235 | hif_ctx = hif_open(cdf_ctx, mode, bus_type, &cbk); |
| 236 | if (!hif_ctx) { |
| 237 | hdd_err("hif_open error"); |
| 238 | return -ENOMEM; |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 239 | } |
| 240 | |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 241 | ret = hdd_init_cds_hif_context(hif_ctx); |
| 242 | if (ret) { |
| 243 | hdd_err("Failed to set global HIF CDS Context err:%d", ret); |
| 244 | goto err_hif_close; |
| 245 | } |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 246 | |
| 247 | ret = hdd_napi_create(); |
| 248 | if (hdd_napi_enabled(HDD_NAPI_ANY)) { |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 249 | hdd_info("hdd_napi_create returned: %d", ret); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 250 | if (ret <= 0) { |
| 251 | hdd_err("NAPI creation error, rc: 0x%x, reinit = %d", |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 252 | ret, reinit); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 253 | ret = -EFAULT; |
| 254 | goto err_hif_close; |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | status = hif_enable(hif_ctx, dev, bdev, bid, bus_type, |
| 259 | (reinit == true) ? HIF_ENABLE_TYPE_REINIT : |
| 260 | HIF_ENABLE_TYPE_PROBE); |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 261 | if (!QDF_IS_STATUS_SUCCESS(status)) { |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 262 | hdd_err("hif_enable error = %d, reinit = %d", |
| 263 | status, reinit); |
| 264 | ret = cdf_status_to_os_return(status); |
| 265 | goto err_napi_destroy; |
| 266 | } |
| 267 | |
| 268 | return 0; |
| 269 | |
| 270 | err_napi_destroy: |
| 271 | hdd_napi_destroy(true); |
| 272 | |
| 273 | err_hif_close: |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 274 | hdd_deinit_cds_hif_context(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 275 | hif_close(hif_ctx); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 276 | return ret; |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | /** |
| 280 | * hdd_hif_close() - HIF close helper |
| 281 | * @hif_ctx: HIF context |
| 282 | * |
| 283 | * Helper function to close HIF |
| 284 | */ |
| 285 | static void hdd_hif_close(void *hif_ctx) |
| 286 | { |
| 287 | if (hif_ctx == NULL) |
| 288 | return; |
| 289 | |
| 290 | hif_disable(hif_ctx, HIF_DISABLE_TYPE_REMOVE); |
| 291 | |
| 292 | hdd_napi_destroy(true); |
| 293 | |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 294 | hdd_deinit_cds_hif_context(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 295 | hif_close(hif_ctx); |
| 296 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 297 | |
| 298 | /** |
Komal Seelam | 48152e1 | 2016-02-09 17:50:33 +0530 | [diff] [blame] | 299 | * hdd_init_cdf_ctx() - API to initialize global CDF Device structure |
| 300 | * @dev: Device Pointer |
| 301 | * @bdev: Bus Device pointer |
| 302 | * |
| 303 | * Return: void |
| 304 | */ |
| 305 | void hdd_init_cdf_ctx(struct device *dev, void *bdev) |
| 306 | { |
| 307 | cdf_device_t cdf_dev = cds_get_context(CDF_MODULE_ID_CDF_DEVICE); |
| 308 | |
| 309 | cdf_dev->dev = dev; |
| 310 | cdf_dev->drv_hdl = bdev; |
| 311 | } |
| 312 | |
| 313 | /** |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 314 | * wlan_hdd_probe() - handles probe request |
| 315 | * |
| 316 | * This function is called to probe the wlan driver |
| 317 | * |
| 318 | * @dev: wlan device structure |
| 319 | * @bdev: bus device structure |
| 320 | * @bid: bus identifier for shared busses |
| 321 | * @bus_type: underlying bus type |
| 322 | * @reinit: true if we are reinitiallizing the driver after a subsystem restart |
| 323 | * |
| 324 | * Return: 0 on successfull probe |
| 325 | */ |
| 326 | static int wlan_hdd_probe(struct device *dev, void *bdev, const hif_bus_id *bid, |
| 327 | enum ath_hal_bus_type bus_type, bool reinit) |
| 328 | { |
| 329 | void *hif_ctx; |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 330 | QDF_STATUS status; |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 331 | int ret = 0; |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 332 | cdf_device_t cdf_dev; |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 333 | uint32_t mode = cds_get_conparam(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 334 | |
| 335 | pr_info("%s: %sprobing driver v%s\n", WLAN_MODULE_NAME, |
| 336 | reinit ? "re-" : "", QWLAN_VERSIONSTR); |
| 337 | |
| 338 | hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); |
| 339 | |
| 340 | /* |
| 341 | * The Krait is going to Idle/Stand Alone Power Save |
| 342 | * more aggressively which is resulting in the longer driver load time. |
| 343 | * The Fix is to not allow Krait to enter Idle Power Save during driver |
| 344 | * load. |
| 345 | */ |
| 346 | hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL); |
| 347 | |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 348 | if (reinit) { |
| 349 | cds_set_recovery_in_progress(true); |
| 350 | } else { |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 351 | ret = hdd_init(); |
| 352 | |
| 353 | if (ret) |
| 354 | goto out; |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 355 | cds_set_load_in_progress(true); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 356 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 357 | |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 358 | if (WLAN_IS_EPPING_ENABLED(mode)) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 359 | status = epping_open(); |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 360 | if (status != QDF_STATUS_SUCCESS) |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 361 | goto err_hdd_deinit; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 362 | } |
| 363 | |
Komal Seelam | 48152e1 | 2016-02-09 17:50:33 +0530 | [diff] [blame] | 364 | hdd_init_cdf_ctx(dev, bdev); |
| 365 | |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 366 | ret = hdd_hif_open(dev, bdev, bid, bus_type, reinit); |
| 367 | |
| 368 | if (ret) |
| 369 | goto err_epping_close; |
| 370 | |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 371 | hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 372 | cdf_dev = cds_get_context(CDF_MODULE_ID_CDF_DEVICE); |
| 373 | |
| 374 | status = ol_cds_init(cdf_dev, hif_ctx); |
| 375 | |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 376 | if (status != QDF_STATUS_SUCCESS) { |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 377 | pr_err("%s No Memory to Create BMI Context\n", __func__); |
| 378 | goto err_hif_close; |
| 379 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 380 | |
| 381 | if (reinit) |
| 382 | ret = hdd_wlan_re_init(hif_ctx); |
| 383 | else |
| 384 | ret = hdd_wlan_startup(dev, hif_ctx); |
| 385 | |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 386 | if (ret) |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 387 | goto err_bmi_close; |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 388 | |
Houston Hoffman | 8eb73ed | 2015-11-02 21:14:55 -0800 | [diff] [blame] | 389 | hif_enable_power_management(hif_ctx); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 390 | |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 391 | if (reinit) { |
| 392 | cds_set_recovery_in_progress(false); |
| 393 | } else { |
| 394 | cds_set_load_in_progress(false); |
| 395 | cds_set_driver_loaded(true); |
| 396 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 397 | |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 398 | hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); |
| 399 | hdd_remove_pm_qos(); |
| 400 | |
| 401 | return 0; |
| 402 | |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 403 | err_bmi_close: |
| 404 | ol_cds_free(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 405 | err_hif_close: |
| 406 | hdd_hif_close(hif_ctx); |
| 407 | err_epping_close: |
Komal Seelam | ad5a90d | 2016-02-16 13:50:03 +0530 | [diff] [blame] | 408 | if (WLAN_IS_EPPING_ENABLED(mode)) |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 409 | epping_close(); |
| 410 | err_hdd_deinit: |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 411 | cds_set_load_in_progress(false); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 412 | hdd_deinit(); |
| 413 | out: |
| 414 | hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); |
| 415 | hdd_remove_pm_qos(); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 416 | return ret; |
| 417 | } |
| 418 | |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 419 | #ifdef CONFIG_CNSS |
| 420 | static inline void hdd_cnss_driver_unloading(void) |
| 421 | { |
| 422 | cnss_set_driver_status(CNSS_LOAD_UNLOAD); |
| 423 | } |
| 424 | #else |
| 425 | static inline void hdd_cnss_driver_unloading(void) { } |
| 426 | #endif |
| 427 | |
| 428 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 429 | /** |
| 430 | * wlan_hdd_remove() - wlan_hdd_remove |
| 431 | * |
| 432 | * This function is called by the platform driver to remove the |
| 433 | * driver |
| 434 | * |
| 435 | * Return: void |
| 436 | */ |
| 437 | static void wlan_hdd_remove(void) |
| 438 | { |
| 439 | void *hif_ctx; |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 440 | |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 441 | pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME, |
| 442 | QWLAN_VERSIONSTR); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 443 | |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 444 | /* Wait for recovery to complete */ |
| 445 | while (cds_is_driver_recovering()) { |
| 446 | hdd_alert("Recovery in progress; wait here!!!"); |
| 447 | msleep(1000); |
| 448 | } |
| 449 | |
| 450 | cds_set_driver_loaded(false); |
| 451 | cds_set_unload_in_progress(true); |
| 452 | |
Rajeev Kumar | dbc886e | 2016-01-19 12:56:04 -0800 | [diff] [blame] | 453 | if (!cds_wait_for_external_threads_completion(__func__)) |
| 454 | hdd_err("External threads are still active attempting driver unload anyway"); |
| 455 | |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 456 | hdd_cnss_driver_unloading(); |
| 457 | |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 458 | hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 459 | |
Houston Hoffman | a0e7106 | 2015-11-18 15:51:32 -0800 | [diff] [blame] | 460 | hif_disable_power_management(hif_ctx); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 461 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 462 | if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 463 | epping_disable(); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 464 | epping_close(); |
| 465 | } else { |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 466 | __hdd_wlan_exit(); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 467 | } |
| 468 | |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 469 | ol_cds_free(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 470 | hdd_hif_close(hif_ctx); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 471 | hdd_deinit(); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 472 | |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 473 | pr_info("%s: Driver Removed\n", WLAN_MODULE_NAME); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 474 | } |
| 475 | |
| 476 | /** |
| 477 | * wlan_hdd_shutdown() - wlan_hdd_shutdown |
| 478 | * |
| 479 | * This is routine is called by platform driver to shutdown the |
| 480 | * driver |
| 481 | * |
| 482 | * Return: void |
| 483 | */ |
| 484 | static void wlan_hdd_shutdown(void) |
| 485 | { |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 486 | void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 487 | |
Rajeev Kumar | fec3dbe | 2016-01-19 15:23:52 -0800 | [diff] [blame] | 488 | if (cds_is_load_or_unload_in_progress()) { |
Jeff Johnson | bd561a9 | 2016-01-07 18:31:35 -0800 | [diff] [blame] | 489 | hdd_err("Load/unload in progress, ignore SSR shutdown"); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 490 | return; |
| 491 | } |
| 492 | /* this is for cases, where shutdown invoked from CNSS */ |
Prashanth Bhatta | 9e14305 | 2015-12-04 11:56:47 -0800 | [diff] [blame] | 493 | cds_set_recovery_in_progress(true); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 494 | |
Rajeev Kumar | dbc886e | 2016-01-19 12:56:04 -0800 | [diff] [blame] | 495 | if (!cds_wait_for_external_threads_completion(__func__)) |
Jeff Johnson | bd561a9 | 2016-01-07 18:31:35 -0800 | [diff] [blame] | 496 | hdd_err("Host is not ready for SSR, attempting anyway"); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 497 | |
Yue Ma | cd96144 | 2015-10-20 16:15:31 -0700 | [diff] [blame] | 498 | if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { |
| 499 | hif_disable_isr(hif_ctx); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 500 | hdd_wlan_shutdown(); |
Yue Ma | cd96144 | 2015-10-20 16:15:31 -0700 | [diff] [blame] | 501 | } |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 502 | |
Komal Seelam | d910649 | 2016-02-15 10:31:44 +0530 | [diff] [blame] | 503 | ol_cds_free(); |
Prashanth Bhatta | 5da711e | 2015-11-30 14:28:52 -0800 | [diff] [blame] | 504 | hdd_hif_close(hif_ctx); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 505 | } |
| 506 | |
| 507 | /** |
| 508 | * wlan_hdd_crash_shutdown() - wlan_hdd_crash_shutdown |
| 509 | * |
| 510 | * HDD crash shutdown funtion: This function is called by |
| 511 | * platfrom driver's crash shutdown routine |
| 512 | * |
| 513 | * Return: void |
| 514 | */ |
| 515 | void wlan_hdd_crash_shutdown(void) |
| 516 | { |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 517 | hif_crash_shutdown(cds_get_context(QDF_MODULE_ID_HIF)); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 518 | } |
| 519 | |
| 520 | /** |
| 521 | * wlan_hdd_notify_handler() - wlan_hdd_notify_handler |
| 522 | * |
| 523 | * This function is called by the platform driver to notify the |
| 524 | * COEX |
| 525 | * |
| 526 | * @state: state |
| 527 | * |
| 528 | * Return: void |
| 529 | */ |
| 530 | void wlan_hdd_notify_handler(int state) |
| 531 | { |
| 532 | if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam())) { |
| 533 | int ret = 0; |
| 534 | ret = hdd_wlan_notify_modem_power_state(state); |
| 535 | if (ret < 0) |
Jeff Johnson | bd561a9 | 2016-01-07 18:31:35 -0800 | [diff] [blame] | 536 | hdd_err("Fail to send notify"); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 537 | } |
| 538 | } |
| 539 | |
| 540 | /** |
| 541 | * __wlan_hdd_bus_suspend() - handles platform supsend |
| 542 | * @state: suspend message from the kernel |
| 543 | * |
| 544 | * Does precondtion validation. Ensures that a subsystem restart isn't in |
| 545 | * progress. Ensures that no load or unload is in progress. |
| 546 | * Calls ol_txrx_bus_suspend to ensure the layer is ready for a bus suspend. |
| 547 | * Calls wma_suspend to configure offloads. |
| 548 | * Calls hif_suspend to suspend the bus. |
| 549 | * |
| 550 | * Return: 0 for success, -EFAULT for null pointers, |
| 551 | * -EBUSY or -EAGAIN if another opperation is in progress and |
| 552 | * wlan will not be ready to suspend in time. |
| 553 | */ |
| 554 | static int __wlan_hdd_bus_suspend(pm_message_t state) |
| 555 | { |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 556 | void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); |
| 557 | void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 558 | int err = wlan_hdd_validate_context(hdd_ctx); |
| 559 | int status; |
| 560 | |
| 561 | hdd_info("event %d", state.event); |
| 562 | |
| 563 | if (err) |
| 564 | goto done; |
| 565 | |
| 566 | err = cdf_status_to_os_return( |
| 567 | ol_txrx_bus_suspend()); |
| 568 | if (err) |
| 569 | goto done; |
| 570 | |
| 571 | err = wma_bus_suspend(); |
| 572 | if (err) |
| 573 | goto resume_oltxrx; |
| 574 | |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 575 | err = hif_bus_suspend(hif_ctx); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 576 | if (err) |
| 577 | goto resume_wma; |
| 578 | |
| 579 | hdd_info("suspend done, status = %d", err); |
| 580 | return err; |
| 581 | |
| 582 | resume_wma: |
| 583 | status = wma_bus_resume(); |
| 584 | CDF_BUG(!status); |
| 585 | resume_oltxrx: |
| 586 | status = ol_txrx_bus_resume(); |
| 587 | CDF_BUG(!status); |
| 588 | done: |
| 589 | hdd_err("suspend done, status = %d", err); |
| 590 | return err; |
| 591 | } |
| 592 | |
| 593 | /** |
| 594 | * wlan_hdd_bus_suspend() - suspend the wlan bus |
| 595 | * |
| 596 | * This function is called by the platform driver to suspend the |
| 597 | * wlan bus |
| 598 | * |
| 599 | * @state: state |
| 600 | * |
Anurag Chouhan | fb54ab0 | 2016-02-18 18:00:46 +0530 | [diff] [blame] | 601 | * Return: QDF_STATUS |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 602 | */ |
| 603 | int wlan_hdd_bus_suspend(pm_message_t state) |
| 604 | { |
| 605 | int ret; |
| 606 | |
| 607 | cds_ssr_protect(__func__); |
| 608 | ret = __wlan_hdd_bus_suspend(state); |
| 609 | cds_ssr_unprotect(__func__); |
| 610 | |
| 611 | return ret; |
| 612 | } |
| 613 | |
| 614 | /** |
| 615 | * __wlan_hdd_bus_resume() - handles platform resume |
| 616 | * |
| 617 | * Does precondtion validation. Ensures that a subsystem restart isn't in |
| 618 | * progress. Ensures that no load or unload is in progress. Ensures that |
| 619 | * it has valid pointers for the required contexts. |
| 620 | * Calls into hif to resume the bus opperation. |
| 621 | * Calls into wma to handshake with firmware and notify it that the bus is up. |
| 622 | * Calls into ol_txrx for symetry. |
| 623 | * Failures are treated as catastrophic. |
| 624 | * |
| 625 | * return: error code or 0 for success |
| 626 | */ |
| 627 | static int __wlan_hdd_bus_resume(void) |
| 628 | { |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 629 | void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); |
| 630 | void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 631 | int status = wlan_hdd_validate_context(hdd_ctx); |
| 632 | |
| 633 | if (0 != status) { |
Jeff Johnson | bd561a9 | 2016-01-07 18:31:35 -0800 | [diff] [blame] | 634 | hdd_err("HDD context is not valid"); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 635 | return status; |
| 636 | } |
| 637 | |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 638 | status = hif_bus_resume(hif_ctx); |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 639 | CDF_BUG(!status); |
| 640 | |
| 641 | status = wma_bus_resume(); |
| 642 | CDF_BUG(!status); |
| 643 | |
| 644 | status = ol_txrx_bus_resume(); |
| 645 | CDF_BUG(!status); |
| 646 | |
| 647 | hdd_info("resume done"); |
| 648 | return status; |
| 649 | } |
| 650 | |
| 651 | /** |
| 652 | * wlan_hdd_bus_resume(): wake up the bus |
| 653 | * |
| 654 | * This function is called by the platform driver to resume wlan |
| 655 | * bus |
| 656 | * |
| 657 | * Return: void |
| 658 | */ |
| 659 | static int wlan_hdd_bus_resume(void) |
| 660 | { |
| 661 | int ret; |
| 662 | |
| 663 | cds_ssr_protect(__func__); |
| 664 | ret = __wlan_hdd_bus_resume(); |
| 665 | cds_ssr_unprotect(__func__); |
| 666 | |
| 667 | return ret; |
| 668 | } |
| 669 | |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 670 | #ifdef FEATURE_RUNTIME_PM |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 671 | /** |
| 672 | * __wlan_hdd_runtime_suspend() - suspend the wlan bus without apps suspend |
| 673 | * |
| 674 | * Each layer is responsible for its own suspend actions. wma_runtime_suspend |
| 675 | * takes care of the parts of the 802.11 suspend that we want to do for runtime |
| 676 | * suspend. |
| 677 | * |
| 678 | * Return: 0 or errno |
| 679 | */ |
| 680 | static int __wlan_hdd_runtime_suspend(void) |
| 681 | { |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 682 | void *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); |
| 683 | void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 684 | int status = wlan_hdd_validate_context(hdd_ctx); |
| 685 | |
Houston Hoffman | 267723f | 2016-01-05 20:08:56 -0800 | [diff] [blame] | 686 | if (0 != status) |
| 687 | goto process_failure; |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 688 | |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 689 | status = hif_pre_runtime_suspend(hif_ctx); |
Houston Hoffman | 267723f | 2016-01-05 20:08:56 -0800 | [diff] [blame] | 690 | if (status) |
| 691 | goto process_failure; |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 692 | |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 693 | status = htc_runtime_suspend(); |
| 694 | if (status) |
Houston Hoffman | 267723f | 2016-01-05 20:08:56 -0800 | [diff] [blame] | 695 | goto process_failure; |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 696 | |
| 697 | status = wma_runtime_suspend(); |
| 698 | if (status) |
| 699 | goto resume_htc; |
| 700 | |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 701 | status = hif_runtime_suspend(hif_ctx); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 702 | if (status) |
| 703 | goto resume_wma; |
| 704 | |
| 705 | status = cnss_auto_suspend(); |
| 706 | if (status) |
| 707 | goto resume_hif; |
| 708 | |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 709 | hif_process_runtime_suspend_success(hif_ctx); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 710 | return status; |
| 711 | |
| 712 | resume_hif: |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 713 | CDF_BUG(!hif_runtime_resume(hif_ctx)); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 714 | resume_wma: |
| 715 | CDF_BUG(!wma_runtime_resume()); |
| 716 | resume_htc: |
| 717 | CDF_BUG(!htc_runtime_resume()); |
Houston Hoffman | 267723f | 2016-01-05 20:08:56 -0800 | [diff] [blame] | 718 | process_failure: |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 719 | hif_process_runtime_suspend_failure(hif_ctx); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 720 | return status; |
| 721 | } |
| 722 | |
| 723 | |
| 724 | /** |
| 725 | * wlan_hdd_runtime_suspend() - suspend the wlan bus without apps suspend |
| 726 | * |
| 727 | * This function is called by the platform driver to suspend the |
| 728 | * wlan bus separately from system suspend |
| 729 | * |
| 730 | * Return: 0 or errno |
| 731 | */ |
| 732 | static int wlan_hdd_runtime_suspend(void) |
| 733 | { |
| 734 | int ret; |
| 735 | |
| 736 | cds_ssr_protect(__func__); |
| 737 | ret = __wlan_hdd_runtime_suspend(); |
| 738 | cds_ssr_unprotect(__func__); |
| 739 | |
| 740 | return ret; |
| 741 | } |
| 742 | |
| 743 | /** |
| 744 | * __wlan_hdd_runtime_resume() - resume the wlan bus from runtime suspend |
| 745 | * |
| 746 | * Sets the runtime pm state and coordinates resume between hif wma and |
| 747 | * ol_txrx. |
| 748 | * |
| 749 | * Return: success since failure is a bug |
| 750 | */ |
| 751 | static int __wlan_hdd_runtime_resume(void) |
| 752 | { |
Anurag Chouhan | 6d76066 | 2016-02-20 16:05:43 +0530 | [diff] [blame^] | 753 | void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 754 | |
| 755 | hif_pre_runtime_resume(hif_ctx); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 756 | CDF_BUG(!cnss_auto_resume()); |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 757 | CDF_BUG(!hif_runtime_resume(hif_ctx)); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 758 | CDF_BUG(!wma_runtime_resume()); |
| 759 | CDF_BUG(!htc_runtime_resume()); |
Komal Seelam | c12e675 | 2016-02-02 18:17:13 +0530 | [diff] [blame] | 760 | hif_process_runtime_resume_success(hif_ctx); |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 761 | return 0; |
| 762 | } |
| 763 | |
| 764 | /** |
| 765 | * wlan_hdd_runtime_resume() - resume the wlan bus from runtime suspend |
| 766 | * |
| 767 | * This function is called by the platform driver to resume the |
| 768 | * wlan bus separately from system suspend |
| 769 | * |
| 770 | * Return: success since failure is a bug |
| 771 | */ |
| 772 | static int wlan_hdd_runtime_resume(void) |
| 773 | { |
| 774 | int ret; |
| 775 | |
| 776 | cds_ssr_protect(__func__); |
| 777 | ret = __wlan_hdd_runtime_resume(); |
| 778 | cds_ssr_unprotect(__func__); |
| 779 | |
| 780 | return ret; |
| 781 | } |
| 782 | #endif |
| 783 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 784 | #ifdef HIF_PCI |
| 785 | /** |
| 786 | * wlan_hdd_pci_probe() - probe callback for pci platform driver |
| 787 | * @pdev: bus dev |
| 788 | * |
| 789 | * Return: void |
| 790 | */ |
| 791 | static int wlan_hdd_pci_probe(struct pci_dev *pdev, |
| 792 | const struct pci_device_id *id) |
| 793 | { |
| 794 | return wlan_hdd_probe(&pdev->dev, pdev, (void *)id, |
| 795 | HAL_BUS_TYPE_PCI, false); |
| 796 | } |
| 797 | |
| 798 | /** |
| 799 | * wlan_hdd_pci_remove() - wlan_hdd_pci_remove |
| 800 | * |
| 801 | * Return: void |
| 802 | */ |
| 803 | void wlan_hdd_pci_remove(struct pci_dev *pdev) |
| 804 | { |
| 805 | wlan_hdd_remove(); |
| 806 | } |
| 807 | |
| 808 | /** |
| 809 | * wlan_hdd_pci_reinit() - wlan_hdd_pci_reinit |
| 810 | * @pdev: bus dev |
| 811 | * @id: bus id |
| 812 | * |
| 813 | * Return: int |
| 814 | */ |
| 815 | int wlan_hdd_pci_reinit(struct pci_dev *pdev, |
| 816 | const struct pci_device_id *id) |
| 817 | { |
| 818 | return wlan_hdd_probe(&pdev->dev, pdev, id, |
| 819 | HAL_BUS_TYPE_PCI, true); |
| 820 | } |
| 821 | |
| 822 | /** |
| 823 | * wlan_hdd_pci_shutdown() - wlan_hdd_pci_shutdown |
| 824 | * @pdev: pdev |
| 825 | * |
| 826 | * Return: void |
| 827 | */ |
| 828 | void wlan_hdd_pci_shutdown(struct pci_dev *pdev) |
| 829 | { |
| 830 | wlan_hdd_shutdown(); |
| 831 | } |
| 832 | |
| 833 | /** |
| 834 | * wlan_hdd_pci_crash_shutdown() - wlan_hdd_pci_crash_shutdown |
| 835 | * @pdev: pdev |
| 836 | * |
| 837 | * Return: void |
| 838 | */ |
| 839 | void wlan_hdd_pci_crash_shutdown(struct pci_dev *pdev) |
| 840 | { |
| 841 | wlan_hdd_crash_shutdown(); |
| 842 | } |
| 843 | |
| 844 | /** |
| 845 | * wlan_hdd_pci_notify_handler() - wlan_hdd_pci_notify_handler |
| 846 | * @pdev: pdev |
| 847 | * @state: state |
| 848 | * |
| 849 | * Return: void |
| 850 | */ |
| 851 | void wlan_hdd_pci_notify_handler(struct pci_dev *pdev, int state) |
| 852 | { |
| 853 | wlan_hdd_notify_handler(state); |
| 854 | } |
| 855 | |
| 856 | /** |
| 857 | * wlan_hdd_pci_suspend() - wlan_hdd_pci_suspend |
| 858 | * @pdev: pdev |
| 859 | * @state: state |
| 860 | * |
| 861 | * Return: void |
| 862 | */ |
| 863 | static int wlan_hdd_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
| 864 | { |
| 865 | return wlan_hdd_bus_suspend(state); |
| 866 | } |
| 867 | |
| 868 | /** |
| 869 | * wlan_hdd_pci_resume() - wlan_hdd_pci_resume |
| 870 | * @pdev: pdev |
| 871 | * |
| 872 | * Return: void |
| 873 | */ |
| 874 | static int wlan_hdd_pci_resume(struct pci_dev *pdev) |
| 875 | { |
| 876 | return wlan_hdd_bus_resume(); |
| 877 | } |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 878 | |
| 879 | #ifdef FEATURE_RUNTIME_PM |
| 880 | /** |
| 881 | * wlan_hdd_pci_runtime_suspend() - wlan_hdd_pci_suspend |
| 882 | * @pdev: pdev |
| 883 | * @state: state |
| 884 | * |
| 885 | * Return: success or errno |
| 886 | */ |
| 887 | static int wlan_hdd_pci_runtime_suspend(struct pci_dev *pdev) |
| 888 | { |
| 889 | return wlan_hdd_runtime_suspend(); |
| 890 | } |
| 891 | |
| 892 | /** |
| 893 | * wlan_hdd_pci_runtime_resume() - runtime resume callback to register with pci |
| 894 | * @pdev: pci device id |
| 895 | * |
| 896 | * Return: success or errno |
| 897 | */ |
| 898 | static int wlan_hdd_pci_runtime_resume(struct pci_dev *pdev) |
| 899 | { |
| 900 | return wlan_hdd_runtime_resume(); |
| 901 | } |
| 902 | #endif |
| 903 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 904 | #else |
| 905 | /** |
| 906 | * wlan_hdd_snoc_probe() - wlan_hdd_snoc_probe |
| 907 | * @dev: dev |
| 908 | * |
| 909 | * Return: int |
| 910 | */ |
| 911 | static int wlan_hdd_snoc_probe(struct device *dev) |
| 912 | { |
| 913 | return wlan_hdd_probe(dev, NULL, NULL, HAL_BUS_TYPE_SNOC, false); |
| 914 | } |
| 915 | |
| 916 | /** |
| 917 | * wlan_hdd_snoc_remove() - wlan_hdd_snoc_remove |
| 918 | * @dev: dev |
| 919 | * |
| 920 | * Return: void |
| 921 | */ |
| 922 | void wlan_hdd_snoc_remove(struct device *dev) |
| 923 | { |
| 924 | wlan_hdd_remove(); |
| 925 | } |
| 926 | |
| 927 | /** |
| 928 | * wlan_hdd_snoc_shutdown() - wlan_hdd_snoc_shutdown |
| 929 | * @dev: dev |
| 930 | * |
| 931 | * Return: void |
| 932 | */ |
| 933 | void wlan_hdd_snoc_shutdown(struct device *dev) |
| 934 | { |
| 935 | wlan_hdd_shutdown(); |
| 936 | } |
| 937 | |
| 938 | /** |
| 939 | * wlan_hdd_snoc_reinit() - wlan_hdd_snoc_reinit |
| 940 | * @dev: dev |
| 941 | * |
| 942 | * Return: int |
| 943 | */ |
| 944 | int wlan_hdd_snoc_reinit(struct device *dev) |
| 945 | { |
| 946 | return wlan_hdd_probe(dev, NULL, NULL, HAL_BUS_TYPE_SNOC, true); |
| 947 | } |
| 948 | |
| 949 | /** |
| 950 | * wlan_hdd_snoc_crash_shutdown() - wlan_hdd_snoc_crash_shutdown |
| 951 | * @dev: dev |
| 952 | * |
| 953 | * Return: void |
| 954 | */ |
| 955 | void wlan_hdd_snoc_crash_shutdown(void *pdev) |
| 956 | { |
| 957 | wlan_hdd_crash_shutdown(); |
| 958 | } |
| 959 | |
| 960 | /** |
| 961 | * wlan_hdd_snoc_suspend() - wlan_hdd_snoc_suspend |
| 962 | * @dev: dev |
| 963 | * @state: state |
| 964 | * |
| 965 | * Return: int |
| 966 | */ |
| 967 | static int wlan_hdd_snoc_suspend(struct device *dev, pm_message_t state) |
| 968 | { |
| 969 | return wlan_hdd_bus_suspend(state); |
| 970 | } |
| 971 | |
| 972 | /** |
| 973 | * wlan_hdd_snoc_resume() - wlan_hdd_snoc_resume |
| 974 | * @dev: dev |
| 975 | * |
| 976 | * Return: int |
| 977 | */ |
| 978 | static int wlan_hdd_snoc_resume(struct device *dev) |
| 979 | { |
| 980 | return wlan_hdd_bus_resume(); |
| 981 | } |
| 982 | #endif /* HIF_PCI */ |
| 983 | |
| 984 | #ifdef HIF_PCI |
| 985 | static struct pci_device_id wlan_hdd_pci_id_table[] = { |
| 986 | { 0x168c, 0x003c, PCI_ANY_ID, PCI_ANY_ID }, |
| 987 | { 0x168c, 0x003e, PCI_ANY_ID, PCI_ANY_ID }, |
| 988 | { 0x168c, 0x0041, PCI_ANY_ID, PCI_ANY_ID }, |
| 989 | { 0x168c, 0xabcd, PCI_ANY_ID, PCI_ANY_ID }, |
| 990 | { 0x168c, 0x7021, PCI_ANY_ID, PCI_ANY_ID }, |
| 991 | { 0 } |
| 992 | }; |
| 993 | |
| 994 | #ifdef CONFIG_CNSS |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 995 | |
| 996 | #ifdef FEATURE_RUNTIME_PM |
| 997 | struct cnss_wlan_runtime_ops runtime_pm_ops = { |
| 998 | .runtime_suspend = wlan_hdd_pci_runtime_suspend, |
| 999 | .runtime_resume = wlan_hdd_pci_runtime_resume, |
| 1000 | }; |
| 1001 | #endif |
| 1002 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 1003 | struct cnss_wlan_driver wlan_drv_ops = { |
| 1004 | .name = "wlan_hdd_pci", |
| 1005 | .id_table = wlan_hdd_pci_id_table, |
| 1006 | .probe = wlan_hdd_pci_probe, |
| 1007 | .remove = wlan_hdd_pci_remove, |
| 1008 | .reinit = wlan_hdd_pci_reinit, |
| 1009 | .shutdown = wlan_hdd_pci_shutdown, |
| 1010 | .crash_shutdown = wlan_hdd_pci_crash_shutdown, |
| 1011 | .modem_status = wlan_hdd_pci_notify_handler, |
| 1012 | #ifdef ATH_BUS_PM |
| 1013 | .suspend = wlan_hdd_pci_suspend, |
| 1014 | .resume = wlan_hdd_pci_resume, |
| 1015 | #endif /* ATH_BUS_PM */ |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 1016 | #ifdef FEATURE_RUNTIME_PM |
| 1017 | .runtime_ops = &runtime_pm_ops, |
| 1018 | #endif |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 1019 | }; |
| 1020 | #else |
| 1021 | MODULE_DEVICE_TABLE(pci, wlan_hdd_pci_id_table); |
| 1022 | struct pci_driver wlan_drv_ops = { |
| 1023 | .name = "wlan_hdd_pci", |
| 1024 | .id_table = wlan_hdd_pci_id_table, |
| 1025 | .probe = wlan_hdd_pci_probe, |
| 1026 | .remove = wlan_hdd_pci_remove, |
| 1027 | #ifdef ATH_BUS_PM |
| 1028 | .suspend = wlan_hdd_pci_suspend, |
| 1029 | .resume = wlan_hdd_pci_resume, |
| 1030 | #endif /* ATH_BUS_PM */ |
Houston Hoffman | e893708 | 2015-11-10 16:49:12 -0800 | [diff] [blame] | 1031 | |
Prakash Dhavali | 7090c5f | 2015-11-02 17:55:19 -0800 | [diff] [blame] | 1032 | }; |
| 1033 | #endif /* CONFIG_CNSS */ |
| 1034 | #else |
| 1035 | struct icnss_driver_ops wlan_drv_ops = { |
| 1036 | .name = "wlan_hdd_drv", |
| 1037 | .probe = wlan_hdd_snoc_probe, |
| 1038 | .remove = wlan_hdd_snoc_remove, |
| 1039 | .shutdown = wlan_hdd_snoc_shutdown, |
| 1040 | .reinit = wlan_hdd_snoc_reinit, |
| 1041 | .crash_shutdown = wlan_hdd_snoc_crash_shutdown, |
| 1042 | .suspend = wlan_hdd_snoc_suspend, |
| 1043 | .resume = wlan_hdd_snoc_resume, |
| 1044 | }; |
| 1045 | #endif |
| 1046 | |
| 1047 | /** |
| 1048 | * wlan_hdd_register_driver() - wlan_hdd_register_driver |
| 1049 | * |
| 1050 | * Return: int |
| 1051 | */ |
| 1052 | int wlan_hdd_register_driver(void) |
| 1053 | { |
| 1054 | return WLAN_HDD_REGISTER_DRIVER(&wlan_drv_ops); |
| 1055 | } |
| 1056 | |
| 1057 | /** |
| 1058 | * wlan_hdd_unregister_driver() - wlan_hdd_unregister_driver |
| 1059 | * |
| 1060 | * Return: void |
| 1061 | */ |
| 1062 | void wlan_hdd_unregister_driver(void) |
| 1063 | { |
| 1064 | WLAN_HDD_UNREGISTER_DRIVER(&wlan_drv_ops); |
| 1065 | } |