diff options
| author | bings <bings@codeaurora.org> | 2019-01-14 18:21:03 +0800 |
|---|---|---|
| committer | bings <bings@codeaurora.org> | 2019-01-17 15:28:27 +0800 |
| commit | cf86e7b4eceb5f95898d224a8c1cb5bb07eb28bf (patch) | |
| tree | 418a5fae66de97674fb4adefe61109812a149652 | |
| parent | e4646b07ba96d4110362310266f05f27d42bc360 (diff) | |
qcacld-2.0: Implement OOB
1.Implement OOB wake up and interrupt api for all interfaces.
2.Implement OOB wake up and interrupt for SDIO interface.
OOB wake up and interrupt can be enable/disable independently.
Change-Id: Id301966d37c752666f453a16d333c32a32aeb2a2
CRs-Fixed: 2382530
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_cfg.h | 48 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 18 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_if_athvar.h | 6 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/hif_oob.c | 260 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/hif_oob.h | 107 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h | 6 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c | 85 | ||||
| -rw-r--r-- | CORE/SERVICES/HTC/htc.c | 37 | ||||
| -rw-r--r-- | CORE/VOSS/inc/i_vos_types.h | 6 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_api.c | 22 | ||||
| -rw-r--r-- | Kbuild | 23 |
11 files changed, 605 insertions, 13 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 98f2f2be228a..9abdef519f3f 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2949,6 +2949,48 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */ #define CFG_P2P_LISTEN_OFFLOAD_ENABLE ( 1 ) #define CFG_P2P_LISTEN_OFFLOAD_DEFAULT ( CFG_P2P_LISTEN_OFFLOAD_DISABLE ) +#ifdef CONFIG_GPIO_OOB +/* + * <ini> + * goob_gpio_num - OOB GPIO NUM + * @Min: 0 + * @Max: 255 + * @Default: 255 + * + * This ini is used to config OOB GPIO NUM + * + * Usage: External + * + * </ini> + */ + +#define CFG_ENABLE_OOB_GPIO_NUM_NAME "goob_gpio_num" +#define CFG_ENABLE_OOB_GPIO_NUM_MIN (0) +#define CFG_ENABLE_OOB_GPIO_NUM_MAX (255) +#define CFG_ENABLE_OOB_GPIO_NUM_DEFAULT (CFG_ENABLE_OOB_GPIO_NUM_MAX) + +/* + * <ini> + * goob_gpio_flag - OOB GPIO flag + * bit 0 - enable OOB wake up + * bit 1 - enable OOB interrupt + * @Min: 0 + * @Max: 3 + * @Default: 0 + * + * This ini is used to enable OOB GPIO feature + * + * Usage: External + * + * </ini> + */ + +#define CFG_ENABLE_OOB_GPIO_FLAG_NAME "goob_gpio_flag" +#define CFG_ENABLE_OOB_GPIO_FLAG_MIN (0) +#define CFG_ENABLE_OOB_GPIO_FLAG_MAX (3) +#define CFG_ENABLE_OOB_GPIO_FLAG_DEFAULT (0) +#endif + /* * Firmware uart print */ @@ -5962,6 +6004,10 @@ struct hdd_config { v_BOOL_t enableTCPChkSumOffld; v_BOOL_t enableIPChecksumOffload; v_BOOL_t enablePowersaveOffload; +#ifdef CONFIG_GPIO_OOB + v_U32_t oob_gpio_num; + v_U32_t oob_gpio_flag; +#endif v_BOOL_t enablefwprint; v_BOOL_t enablefwlog; v_BOOL_t fastfwdump; diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 6fc2a9472f0f..f7ffdb69533d 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2954,6 +2954,22 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_POWERSAVE_OFFLOAD_MIN, CFG_POWERSAVE_OFFLOAD_MAX ), +#ifdef CONFIG_GPIO_OOB + REG_VARIABLE(CFG_ENABLE_OOB_GPIO_FLAG_NAME, WLAN_PARAM_Integer, + hdd_config_t, oob_gpio_flag, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENABLE_OOB_GPIO_FLAG_DEFAULT, + CFG_ENABLE_OOB_GPIO_FLAG_MIN, + CFG_ENABLE_OOB_GPIO_FLAG_MAX), + + REG_VARIABLE(CFG_ENABLE_OOB_GPIO_NUM_NAME, WLAN_PARAM_Integer, + hdd_config_t, oob_gpio_num, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_ENABLE_OOB_GPIO_NUM_DEFAULT, + CFG_ENABLE_OOB_GPIO_NUM_MIN, + CFG_ENABLE_OOB_GPIO_NUM_MAX), +#endif + REG_VARIABLE( CFG_ENABLE_FW_UART_PRINT_NAME, WLAN_PARAM_Integer, hdd_config_t, enablefwprint, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, diff --git a/CORE/SERVICES/COMMON/ol_if_athvar.h b/CORE/SERVICES/COMMON/ol_if_athvar.h index ee980552f62e..9946586ebbce 100644 --- a/CORE/SERVICES/COMMON/ol_if_athvar.h +++ b/CORE/SERVICES/COMMON/ol_if_athvar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -245,6 +245,10 @@ struct ol_softc { #ifdef PERE_IP_HDR_ALIGNMENT_WAR bool host_80211_enable; /* Enables native-wifi mode on host */ #endif +#ifdef CONFIG_GPIO_OOB + u_int32_t oob_gpio_num; + u_int32_t oob_gpio_flag; +#endif bool enableuartprint; /* enable uart/serial prints from target */ bool enablefwlog; /* enable fwlog */ /* enable FW self-recovery for Rome USB */ diff --git a/CORE/SERVICES/HIF/hif_oob.c b/CORE/SERVICES/HIF/hif_oob.c new file mode 100644 index 000000000000..e50f931f2c73 --- /dev/null +++ b/CORE/SERVICES/HIF/hif_oob.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/gpio.h> +#include <hif_oob.h> +#include <vos_api.h> +#if defined(HIF_SDIO) +#include <hif_internal.h> +#endif +#define ATH_MODULE_NAME hif +#include "a_debug.h" + +#if defined(HIF_SDIO) +#define hif_device_oob_ctx(device) (&((device)->hif_oob)) +#define hif_oob_irq_handler_ctx(device) ((device)->func) +#else +/*Please add oob context if USB, PCIE supports OOB*/ +#define hif_device_oob_ctx(device) NULL +#define hif_oob_irq_handler_ctx(device) NULL +#endif + +#define OOB_INVALID_GPIO 255 +/** + * hif_oob_irq() - oob irq handler + * @irq: irq number + * @dev_id: HIF DEVICE + * + * Return: IRQ_HANDLED + */ +static irqreturn_t hif_oob_irq(int irq, void *dev) +{ + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx((HIF_DEVICE *)dev); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return IRQ_HANDLED; + } + + if (hif_oob->oob_gpio_flag & GPIO_OOB_INTERRUPT_ENABLE) + up(&hif_oob->oob_sem); + + return IRQ_HANDLED; +} + +/** + * oob_task() - thread to handle all the oob interrupts + * @pm_oob: HIF DEVICE + * + * Return: 0 + */ +static int oob_task(void *pm_oob) +{ + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx((HIF_DEVICE *)pm_oob); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return A_ERROR; + } + while (!hif_oob->oob_shutdown) { + if (down_interruptible(&hif_oob->oob_sem) != 0) + continue; + while (!gpio_get_value(hif_oob->oob_gpio_num)) + hif_oob->oob_irq_handler( + hif_oob_irq_handler_ctx((HIF_DEVICE *)pm_oob)); + } + + complete_and_exit(&hif_oob->oob_completion, 0); + + return 0; +} + +int hif_oob_claim_irq(oob_irq_handler_t handler, HIF_DEVICE *hif_device) +{ + struct sched_param param = { .sched_priority = 1 }; + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx(hif_device); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return A_ERROR; + } + if (hif_oob->oob_task) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("oob task already created")); + return 0; + } + sema_init(&hif_oob->oob_sem, 0); + hif_oob->oob_task = kthread_create(oob_task, hif_device, + "koobirqd"); + if (IS_ERR(hif_oob->oob_task)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("fail to create oob task")); + hif_oob->oob_task = NULL; + return A_ERROR; + } else { + hif_oob->oob_irq_handler = handler; + hif_oob->oob_shutdown = 0; + sched_setscheduler(hif_oob->oob_task, SCHED_FIFO, + ¶m); + wake_up_process(hif_oob->oob_task); + up(&hif_oob->oob_sem); + AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("start oob task")); + } + + return 0; +} + +int hif_oob_release_irq(HIF_DEVICE *hif_device) +{ + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx(hif_device); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return A_ERROR; + } + if (!hif_oob->oob_task) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("oob_task is NULL. return")); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("try to kill the oob task")); + init_completion(&hif_oob->oob_completion); + hif_oob->oob_shutdown = 1; + up(&hif_oob->oob_sem); + wait_for_completion(&hif_oob->oob_completion); + hif_oob->oob_task = NULL; + } + + return 0; +} + +void hif_oob_gpio_deinit(HIF_DEVICE *device) +{ + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx(device); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return; + } + + if (hif_oob->oob_irq_num >= 0 && hif_oob->oob_gpio_flag) { + if (hif_oob->oob_irq_wake_enabled) { + if (!disable_irq_wake(hif_oob->oob_irq_num)) + hif_oob->oob_irq_wake_enabled = false; + } + disable_irq(hif_oob->oob_irq_num); + free_irq(hif_oob->oob_irq_num, device); + gpio_free(hif_oob->oob_gpio_num); + hif_oob->oob_irq_num = -1; + } +} + +int hif_oob_gpio_init(HIF_DEVICE *device, uint32_t oob_gpio, + uint32_t oob_gpio_flag) +{ + int ret = 0; + unsigned long irq_flags = 0; + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx(device); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return A_ERROR; + } + + ret = gpio_request(oob_gpio, "oob_irq"); + + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("gpio_request %d ret %d", oob_gpio, ret)); + goto err_oob_req; + } + + ret = gpio_direction_input(oob_gpio); + + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("gpio_direction_input %d ret %d", oob_gpio, ret)); + goto err_oob_int; + } + + hif_oob->oob_irq_num = gpio_to_irq(oob_gpio); + if (hif_oob->oob_irq_num < 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: gpio_to_irq %d ret %d", __func__, oob_gpio, ret)); + goto err_oob_int; + } + + if (oob_gpio_flag & GPIO_OOB_INTERRUPT_ENABLE) + irq_flags = IRQF_TRIGGER_FALLING; + else + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; + + ret = request_irq(hif_oob->oob_irq_num, hif_oob_irq, irq_flags, + "oob_irq", device); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: request_irq %d ret %d", __func__, oob_gpio, ret)); + goto err_oob_int; + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: gpio %d request oob irq", __func__, oob_gpio)); + if (oob_gpio_flag & GPIO_OOB_WAKEUP_ENABLE) { + ret = enable_irq_wake(hif_oob->oob_irq_num); + if (ret) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("enable irq wake failed %d", ret)); + hif_oob->oob_irq_wake_enabled = false; + goto err_oob_wakeup; + } else { + hif_oob->oob_irq_wake_enabled = true; + } + } + } + hif_oob->oob_gpio_num = oob_gpio; + hif_oob->oob_gpio_flag = oob_gpio_flag; + + return ret; + +err_oob_wakeup: + disable_irq(hif_oob->oob_irq_num); + free_irq(hif_oob->oob_irq_num, device); +err_oob_int: + gpio_free(oob_gpio); +err_oob_req: + hif_oob->oob_irq_num = -1; + hif_oob->oob_gpio_num = OOB_INVALID_GPIO; + hif_oob->oob_irq_wake_enabled = false; + return ret; +} + +int hif_set_wow_maskint(HIF_DEVICE *device, bool value) +{ + struct hif_oob_ctx *hif_oob = hif_device_oob_ctx(device); + + if (!hif_oob) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("NULL hif oob\n")); + + return A_ERROR; + } + + hif_oob->wow_maskint = value; + + return A_OK; +} diff --git a/CORE/SERVICES/HIF/hif_oob.h b/CORE/SERVICES/HIF/hif_oob.h new file mode 100644 index 000000000000..0d045e1d510f --- /dev/null +++ b/CORE/SERVICES/HIF/hif_oob.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _HIF_OOB_H_ +#define _HIF_OOB_H_ + +#include <linux/kthread.h> + +#include <hif.h> + +#define GPIO_OOB_WAKEUP_ENABLE (1 << 0) + +#define GPIO_OOB_INTERRUPT_ENABLE (1 << 1) + +#ifdef CONFIG_GPIO_OOB +typedef void (*oob_irq_handler_t) (void *dev_para); + +struct hif_oob_ctx { + struct semaphore oob_sem; + struct completion oob_completion; + struct task_struct *oob_task; + int oob_irq_num; + uint32_t oob_gpio_num; + uint32_t oob_gpio_flag; + bool oob_irq_wake_enabled; + bool oob_shutdown; + oob_irq_handler_t oob_irq_handler; + bool wow_maskint; +}; + +/** + * hif_oob_gpio_init() - initialize gpio oob + * @device: HIF handle + * @oob_gpio: oob gpio number + * @oob_gpio_flag: oob gpio flag + * + * Return: 0 if succeeds. + */ +int hif_oob_gpio_init(HIF_DEVICE *device, uint32_t oob_gpio, + uint32_t oob_gpio_flag); + +/** + * hif_oob_gpio_deinit() - deinitialize gpio oob + * @device: HIF handle + * + * Return: NULL + */ +void hif_oob_gpio_deinit(HIF_DEVICE *device); + +/** + * hif_oob_claim_irq() - create oob task + * @handler: oob irq handler + * @hif_device: HIF DEVICE + * + * Return: 0 if succeeds + */ +int hif_oob_claim_irq(oob_irq_handler_t handler, HIF_DEVICE *hif_device); + +/** + * hif_oob_release_irq() - delete oob task + * @hif_device: HIF DEVICE + * + * Return: 0 + */ +int hif_oob_release_irq(HIF_DEVICE *hif_device); + +/** + * hif_set_wow_maskint() - configure wow maskint + * @hif_device: HIF DEVICE + * @value: value to set + * + * Return: 0 if succeeds + */ +int hif_set_wow_maskint(HIF_DEVICE *device, bool value); +#else +static inline int hif_oob_gpio_init(HIF_DEVICE *device, uint32_t oob_gpio, + uint32_t oob_gpio_flag) +{ + return 0; +} + +static inline void hif_oob_gpio_deinit(HIF_DEVICE *device) +{ +} + +static inline int hif_set_wow_maskint(HIF_DEVICE *device, bool value) +{ + return 0; +} +#endif + +#endif diff --git a/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h b/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h index 9d3ae4f07093..947a544e30ca 100644 --- a/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h +++ b/CORE/SERVICES/HIF/sdio/linux/native_sdio/include/hif_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -36,6 +36,7 @@ #include <adf_os_lock.h> #include "hif.h" #include "hif_sdio_common.h" +#include "hif_oob.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) #include <linux/scatterlist.h> #define HIF_LINUX_MMC_SCATTER_SUPPORT @@ -135,6 +136,9 @@ struct hif_device { /* mailbox swapping for control and data svc*/ A_BOOL swap_mailbox; bool ctrl_response_timeout; +#ifdef CONFIG_GPIO_OOB + struct hif_oob_ctx hif_oob; +#endif }; #define HIF_DMA_BUFFER_SIZE (4 * 1024) diff --git a/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c b/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c index 894f20b6b44a..8cfcc97b0223 100644 --- a/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c +++ b/CORE/SERVICES/HIF/sdio/linux/native_sdio/src/hif.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1873,10 +1873,86 @@ HIFAckInterrupt(HIF_DEVICE *device) /* Acknowledge our function IRQ */ } +#ifdef CONFIG_GPIO_OOB void HIFUnMaskInterrupt(HIF_DEVICE *device) { - int ret;; + int ret; + + if (!device || !device->func) + return; + + ENTER(); + /* + * On HP Elitebook 8460P, interrupt mode is not stable in high + * throughput, so polling method should be used instead of + * interrupt mode + */ + if (brokenirq) { + pr_err("AR6000:Using broken IRQ mode\n"); + /* disable IRQ support even the capability exists */ + device->func->card->host->caps &= ~MMC_CAP_SDIO_IRQ; + } + /* Register the IRQ Handler */ + sdio_claim_host(device->func); + if (device->hif_oob.oob_gpio_flag & GPIO_OOB_INTERRUPT_ENABLE) { + ret = hif_oob_claim_irq(hif_oob_irq_handler, device); + } else { + if (false == vos_oob_enabled()) + ret = sdio_claim_irq(device->func, hifIRQHandler); + else + ret = vos_register_oob_irq_handler(hif_oob_irq_handler, + device->func); + } + + sdio_release_host(device->func); + AR_DEBUG_ASSERT(ret == 0); + EXIT(); +} + +void HIFMaskInterrupt(HIF_DEVICE *device) +{ + int ret; + + if (!device || !device->func) + return; + ENTER(); + + /* Mask our function IRQ */ + sdio_claim_host(device->func); + while (atomic_read(&device->irqHandling)) { + sdio_release_host(device->func); + schedule_timeout_interruptible(HZ / 10); + sdio_claim_host(device->func); + } + + if (device->hif_oob.oob_gpio_flag & GPIO_OOB_INTERRUPT_ENABLE) { + ret = hif_oob_release_irq(device); + } else { + if (false == vos_oob_enabled()) + ret = sdio_release_irq(device->func); + else + ret = vos_unregister_oob_irq_handler(device->func); + } + + sdio_release_host(device->func); + if (ret) { + if (ret == -ETIMEDOUT) { + AR_DEBUG_PRINTF(ATH_DEBUG_WARN, + ("AR6000: Timeout mask interrupt. Card rm?")); + } else { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, + ("AR6000: Unable to mask interrupt %d\n", ret)); + AR_DEBUG_ASSERT(ret == 0); + } + } + EXIT(); +} +#else +void +HIFUnMaskInterrupt(HIF_DEVICE *device) +{ + int ret; if (device == NULL || device->func == NULL) return; @@ -1937,6 +2013,7 @@ void HIFMaskInterrupt(HIF_DEVICE *device) } EXIT(); } +#endif void hif_release_bus_requests(HIF_DEVICE *device) { @@ -2397,6 +2474,7 @@ static int hifDeviceSuspend(struct device *dev) AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: set sdio pm flags MMC_PM_WAKE_SDIO_IRQ failed: %d\n",ret)); return ret; } + hif_set_wow_maskint(device, true); HIFMaskInterrupt(device); device->DeviceState = HIF_DEVICE_STATE_WOW; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: wow success\n")); @@ -2414,6 +2492,7 @@ static int hifDeviceSuspend(struct device *dev) * But before adding finishe callback function to these handler, sleep wait is a simple method. */ msleep(100); + hif_set_wow_maskint(device, true); HIFMaskInterrupt(device); device->DeviceState = HIF_DEVICE_STATE_DEEPSLEEP; AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("hifDeviceSuspend: deep sleep success\n")); @@ -2486,6 +2565,7 @@ static int hifDeviceResume(struct device *dev) } } else if(device->DeviceState == HIF_DEVICE_STATE_DEEPSLEEP){ + hif_set_wow_maskint(device, false); HIFUnMaskInterrupt(device); // hifRestartAllVap((struct ol_ath_softc_net80211 *)device->claimedContext); } @@ -2501,6 +2581,7 @@ static int hifDeviceResume(struct device *dev) return status; } /*TODO:WOW support*/ + hif_set_wow_maskint(device, false); HIFUnMaskInterrupt(device); } diff --git a/CORE/SERVICES/HTC/htc.c b/CORE/SERVICES/HTC/htc.c index 09936a01b5de..0667c6c597f9 100644 --- a/CORE/SERVICES/HTC/htc.c +++ b/CORE/SERVICES/HTC/htc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -35,6 +35,7 @@ #include <vos_getBin.h> #include "epping_main.h" #include "htc_api.h" +#include <hif_oob.h> #define MAX_HTC_RX_BUNDLE 2 @@ -309,6 +310,7 @@ void HTCDestroy(HTC_HANDLE HTCHandle) HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%pK \n",target)); HIFStop(HTCGetHifDevice(HTCHandle)); + hif_oob_gpio_deinit(HTCGetHifDevice(HTCHandle)); HTCCleanup(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n")); } @@ -528,6 +530,30 @@ A_UINT8 HTCGetCreditAllocation(HTC_TARGET *target, A_UINT16 ServiceID) return allocation; } +/** + * get_oob_gpio_config() - get oob gpio config + * @HTCHandle - pointer to HTC handle + * @gpio_num - pointer to gpio num + * @gpio_flag - pointer to gpio flag + * + * Return NULL + */ +#ifdef CONFIG_GPIO_OOB +static void get_oob_gpio_config(HTC_HANDLE htc_handle, uint32_t *gpio_num, + uint32_t *gpio_flag) +{ + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(htc_handle); + struct ol_softc *scn = (struct ol_softc *)target->HTCInitInfo.pContext; + + *gpio_num = scn->oob_gpio_num; + *gpio_flag = scn->oob_gpio_flag; +} +#else +static void get_oob_gpio_config(HTC_HANDLE htc_handle, uint32_t *gpio_num, + uint32_t *gpio_flag) +{ +} +#endif A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) { @@ -540,12 +566,18 @@ A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle) A_UINT16 htc_rdy_msg_id; A_UINT8 i = 0; HTC_PACKET *pRxBundlePacket, *pTempBundlePacket; + uint32_t gpio_num = 0; + uint32_t gpio_flag = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%pK) \n", HTCHandle)); AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("+HWT\n")); do { - + get_oob_gpio_config(HTCHandle, &gpio_num, &gpio_flag); + if (gpio_flag) { + if (hif_oob_gpio_init(target->hif_dev, gpio_num, gpio_flag)) + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("OOB init failed\n")); + } status = HIFStart(target->hif_dev); if (A_FAILED(status)) { AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIFStart failed\n")); @@ -800,6 +832,7 @@ void HTCStop(HTC_HANDLE HTCHandle) */ HIFStop(target->hif_dev); + hif_oob_gpio_deinit(target->hif_dev); #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); diff --git a/CORE/VOSS/inc/i_vos_types.h b/CORE/VOSS/inc/i_vos_types.h index 756234d33189..d097eee96cc1 100644 --- a/CORE/VOSS/inc/i_vos_types.h +++ b/CORE/VOSS/inc/i_vos_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014, 2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -38,6 +38,10 @@ #include <linux/version.h> #include <asm/div64.h> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) +#include <uapi/linux/sched/types.h> +#endif + /**========================================================================= \file i_vos_Types.h diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 825cfd88d815..15f878e0fc4e 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -413,7 +413,24 @@ static void vos_set_ac_specs_params(tMacOpenParameters *param, } } - +/** + * set_oob_gpio_config() - set oob gpio config + * @scn: pointer to scn + * @hdd_ctx: pointer to hdd_ctx + * + * Return NULL + */ +#ifdef CONFIG_GPIO_OOB +static void set_oob_gpio_config(struct ol_softc *scn, hdd_context_t *hdd_ctx) +{ + scn->oob_gpio_num = hdd_ctx->cfg_ini->oob_gpio_num; + scn->oob_gpio_flag = hdd_ctx->cfg_ini->oob_gpio_flag; +} +#else +static void set_oob_gpio_config(struct ol_softc *scn, hdd_context_t *hdd_ctx) +{ +} +#endif /*--------------------------------------------------------------------------- \brief vos_open() - Open the vOSS Module @@ -547,6 +564,7 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize ) scn->enableFwSelfRecovery = pHddCtx->cfg_ini->enableFwSelfRecovery; scn->fastfwdump_host = pHddCtx->cfg_ini->fastfwdump; scn->max_no_of_peers = pHddCtx->max_peers; + set_oob_gpio_config(scn, pHddCtx); #ifdef WLAN_FEATURE_LPSS scn->enablelpasssupport = pHddCtx->cfg_ini->enablelpasssupport; #endif @@ -396,6 +396,10 @@ HIF_COMMON_DIR := CORE/SERVICES/HIF/common HIF_COMMON_OBJS := $(HIF_COMMON_DIR)/hif_bmi_reg_access.o \ $(HIF_COMMON_DIR)/hif_diag_reg_access.o +ifeq ($(CONFIG_GPIO_OOB),y) +HIF_DIR_OBJS += $(HIF_DIR)/hif_oob.o +endif + HIF_SDIO_DIR := CORE/SERVICES/HIF/sdio HIF_SDIO_OBJS := $(HIF_SDIO_DIR)/hif_sdio_send.o \ $(HIF_SDIO_DIR)/hif_sdio_dev.o \ @@ -415,6 +419,7 @@ HIF_SDIO_NATIVE_OBJS := $(HIF_SDIO_NATIVE_SRC_DIR)/hif.o \ $(HIF_SDIO_NATIVE_SRC_DIR)/hif_scatter.o HIF_INC := -I$(WLAN_ROOT)/$(HIF_COMMON_DIR) \ + -I$(WLAN_ROOT)/$(HIF_DIR) \ -I$(WLAN_ROOT)/$(HIF_SDIO_DIR) \ -I$(WLAN_ROOT)/$(HIF_SDIO_LINUX_DIR) \ -I$(WLAN_ROOT)/$(HIF_SDIO_NATIVE_INC_DIR) \ @@ -869,10 +874,15 @@ HIF_DIR := CORE/SERVICES/HIF ifeq ($(CONFIG_HIF_PCI), 1) HIF_PCIE_DIR := $(HIF_DIR)/PCIe -HIF_INC := -I$(WLAN_ROOT)/$(HIF_PCIE_DIR) +HIF_INC := -I$(WLAN_ROOT)/$(HIF_PCIE_DIR) \ + -I$(WLAN_ROOT)/$(HIF_DIR) HIF_OBJS := $(HIF_DIR)/ath_procfs.o +ifeq ($(CONFIG_GPIO_OOB),y) +HIF_OBJS += $(HIF_DIR)/hif_oob.o +endif + HIF_PCIE_OBJS := $(HIF_PCIE_DIR)/copy_engine.o \ $(HIF_PCIE_DIR)/hif_pci.o \ $(HIF_PCIE_DIR)/if_pci.o \ @@ -884,10 +894,15 @@ endif ifeq ($(CONFIG_HIF_USB), 1) HIF_USB_DIR := $(HIF_DIR)/USB -HIF_INC := -I$(WLAN_ROOT)/$(HIF_USB_DIR) +HIF_INC := -I$(WLAN_ROOT)/$(HIF_USB_DIR) \ + -I$(WLAN_ROOT)/$(HIF_DIR) HIF_OBJS := $(HIF_DIR)/ath_procfs.o +ifeq ($(CONFIG_GPIO_OOB),y) +HIF_OBJS += $(HIF_DIR)/hif_oob.o +endif + HIF_USB_OBJS := $(HIF_USB_DIR)/usbdrv.o \ $(HIF_USB_DIR)/hif_usb.o \ $(HIF_USB_DIR)/if_usb.o \ @@ -1633,6 +1648,10 @@ CDEFINES += -DCONFIG_NON_QC_PLATFORM CDEFINES += -DTARGET_DUMP_FOR_NON_QC_PLATFORM endif +ifeq ($(CONFIG_GPIO_OOB),y) +CDEFINES += -DCONFIG_GPIO_OOB +endif + ifeq ($(CONFIG_NON_QC_PLATFORM), y) ifeq ($(CONFIG_ROME_IF),pci) CDEFINES += -DCONFIG_NON_QC_PLATFORM_PCI |
