Loading drivers/net/wireless/cnss2/main.c +3 −0 Original line number Diff line number Diff line Loading @@ -523,6 +523,9 @@ static void cnss_driver_event_work(struct work_struct *work) ret = cnss_wlfw_server_exit(plat_priv); break; case CNSS_DRIVER_EVENT_REQUEST_MEM: ret = cnss_pci_alloc_fw_mem(plat_priv->bus_priv); if (ret) break; ret = cnss_wlfw_respond_mem_send_sync(plat_priv); break; case CNSS_DRIVER_EVENT_FW_MEM_READY: Loading drivers/net/wireless/cnss2/pci.c +72 −6 Original line number Diff line number Diff line Loading @@ -620,6 +620,43 @@ out: } EXPORT_SYMBOL(cnss_auto_resume); int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *fw_mem = &plat_priv->fw_mem; if (!fw_mem->va && fw_mem->size) { fw_mem->va = dma_alloc_coherent(&pci_priv->pci_dev->dev, fw_mem->size, &fw_mem->pa, GFP_KERNEL); if (!fw_mem->va) { cnss_pr_err("Failed to allocate memory for FW, size: 0x%zx\n", fw_mem->size); fw_mem->size = 0; return -ENOMEM; } } return 0; } static void cnss_pci_free_fw_mem(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *fw_mem = &plat_priv->fw_mem; if (fw_mem->va && fw_mem->size) { cnss_pr_dbg("Freeing memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n", fw_mem->va, &fw_mem->pa, fw_mem->size); dma_free_coherent(&pci_priv->pci_dev->dev, fw_mem->size, fw_mem->va, fw_mem->pa); fw_mem->va = NULL; fw_mem->pa = 0; fw_mem->size = 0; } } int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va, phys_addr_t *pa) { Loading Loading @@ -876,6 +913,30 @@ static void cnss_mhi_pm_runtime_put_noidle(struct pci_dev *pci_dev) pm_runtime_put_noidle(&pci_dev->dev); } static char *mhi_dev_state_to_str(enum mhi_dev_ctrl state) { switch (state) { case MHI_DEV_CTRL_INIT: return "INIT"; case MHI_DEV_CTRL_DE_INIT: return "DEINIT"; case MHI_DEV_CTRL_POWER_ON: return "POWER_ON"; case MHI_DEV_CTRL_POWER_OFF: return "POWER_OFF"; case MHI_DEV_CTRL_SUSPEND: return "SUSPEND"; case MHI_DEV_CTRL_RESUME: return "RESUME"; case MHI_DEV_CTRL_RAM_DUMP: return "RAM_DUMP"; case MHI_DEV_CTRL_NOTIFY_LINK_ERROR: return "NOTIFY_LINK_ERROR"; default: return "UNKNOWN"; } }; static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) { int ret = 0; Loading Loading @@ -971,11 +1032,13 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, return 0; break; default: cnss_pr_err("Unhandled MHI DEV state (%d)\n", mhi_dev_state); cnss_pr_err("Unhandled MHI DEV state: %s(%d)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state); } cnss_pr_err("Cannot set MHI DEV state (%d) in current MHI state (0x%lx)\n", mhi_dev_state, pci_priv->mhi_state); cnss_pr_err("Cannot set MHI DEV state %s(%d) in current MHI state (0x%lx)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state, pci_priv->mhi_state); return -EINVAL; } Loading Loading @@ -1027,11 +1090,12 @@ int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, if (ret) goto out; cnss_pr_dbg("Setting MHI DEV state (%d)\n", mhi_dev_state); cnss_pr_dbg("Setting MHI DEV state: %s(%d)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state); ret = mhi_pm_control_device(&pci_priv->mhi_dev, mhi_dev_state); if (ret) { cnss_pr_err("Failed to set MHI DEV state (%d)\n", mhi_dev_state); cnss_pr_err("Failed to set MHI DEV state: %s(%d)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state); goto out; } Loading Loading @@ -1197,6 +1261,8 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(&pci_dev->dev); cnss_pci_free_fw_mem(pci_priv); if (pci_dev->device == QCA6290_DEVICE_ID) { cnss_pci_unregister_mhi(pci_priv); cnss_pci_disable_msi(pci_priv); Loading drivers/net/wireless/cnss2/pci.h +1 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,7 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); void cnss_pci_deinit(struct cnss_plat_data *plat_priv); int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv); int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va, phys_addr_t *pa); int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, Loading drivers/net/wireless/cnss2/qmi.c +8 −26 Original line number Diff line number Diff line /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -257,15 +257,9 @@ int cnss_wlfw_respond_mem_send_sync(struct cnss_plat_data *plat_priv) cnss_pr_dbg("Sending respond memory message, state: 0x%lx\n", plat_priv->driver_state); if (!fw_mem->va && fw_mem->size) { fw_mem->va = dma_alloc_coherent(&plat_priv->plat_dev->dev, fw_mem->size, &fw_mem->pa, GFP_KERNEL); if (!fw_mem->va) { cnss_pr_err("Failed to allocate memory for FW, size: 0x%zx\n", fw_mem->size); fw_mem->size = 0; } if (!fw_mem->pa || !fw_mem->size) { cnss_pr_err("Memory for FW is not available!\n"); goto out; } cnss_pr_dbg("Memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n", Loading @@ -274,8 +268,8 @@ int cnss_wlfw_respond_mem_send_sync(struct cnss_plat_data *plat_priv) memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); req.addr = plat_priv->fw_mem.pa; req.size = plat_priv->fw_mem.size; req.addr = fw_mem->pa; req.size = fw_mem->size; req_desc.max_msg_len = WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN; req_desc.msg_id = QMI_WLFW_RESPOND_MEM_REQ_V01; Loading Loading @@ -526,6 +520,7 @@ int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv, return 0; out: if (mode != QMI_WLFW_OFF_V01) CNSS_ASSERT(0); return ret; } Loading Loading @@ -676,8 +671,6 @@ err_create_handle: int cnss_wlfw_server_exit(struct cnss_plat_data *plat_priv) { struct cnss_fw_mem *fw_mem; if (!plat_priv) return -ENODEV; Loading @@ -685,17 +678,6 @@ int cnss_wlfw_server_exit(struct cnss_plat_data *plat_priv) clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); clear_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state); fw_mem = &plat_priv->fw_mem; if (fw_mem->va && fw_mem->size) { cnss_pr_dbg("Freeing memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n", fw_mem->va, &fw_mem->pa, fw_mem->size); dma_free_coherent(&plat_priv->plat_dev->dev, fw_mem->size, fw_mem->va, fw_mem->pa); fw_mem->va = NULL; fw_mem->pa = 0; fw_mem->size = 0; } cnss_pr_info("QMI WLFW service disconnected, state: 0x%lx\n", plat_priv->driver_state); Loading Loading
drivers/net/wireless/cnss2/main.c +3 −0 Original line number Diff line number Diff line Loading @@ -523,6 +523,9 @@ static void cnss_driver_event_work(struct work_struct *work) ret = cnss_wlfw_server_exit(plat_priv); break; case CNSS_DRIVER_EVENT_REQUEST_MEM: ret = cnss_pci_alloc_fw_mem(plat_priv->bus_priv); if (ret) break; ret = cnss_wlfw_respond_mem_send_sync(plat_priv); break; case CNSS_DRIVER_EVENT_FW_MEM_READY: Loading
drivers/net/wireless/cnss2/pci.c +72 −6 Original line number Diff line number Diff line Loading @@ -620,6 +620,43 @@ out: } EXPORT_SYMBOL(cnss_auto_resume); int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *fw_mem = &plat_priv->fw_mem; if (!fw_mem->va && fw_mem->size) { fw_mem->va = dma_alloc_coherent(&pci_priv->pci_dev->dev, fw_mem->size, &fw_mem->pa, GFP_KERNEL); if (!fw_mem->va) { cnss_pr_err("Failed to allocate memory for FW, size: 0x%zx\n", fw_mem->size); fw_mem->size = 0; return -ENOMEM; } } return 0; } static void cnss_pci_free_fw_mem(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_fw_mem *fw_mem = &plat_priv->fw_mem; if (fw_mem->va && fw_mem->size) { cnss_pr_dbg("Freeing memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n", fw_mem->va, &fw_mem->pa, fw_mem->size); dma_free_coherent(&pci_priv->pci_dev->dev, fw_mem->size, fw_mem->va, fw_mem->pa); fw_mem->va = NULL; fw_mem->pa = 0; fw_mem->size = 0; } } int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va, phys_addr_t *pa) { Loading Loading @@ -876,6 +913,30 @@ static void cnss_mhi_pm_runtime_put_noidle(struct pci_dev *pci_dev) pm_runtime_put_noidle(&pci_dev->dev); } static char *mhi_dev_state_to_str(enum mhi_dev_ctrl state) { switch (state) { case MHI_DEV_CTRL_INIT: return "INIT"; case MHI_DEV_CTRL_DE_INIT: return "DEINIT"; case MHI_DEV_CTRL_POWER_ON: return "POWER_ON"; case MHI_DEV_CTRL_POWER_OFF: return "POWER_OFF"; case MHI_DEV_CTRL_SUSPEND: return "SUSPEND"; case MHI_DEV_CTRL_RESUME: return "RESUME"; case MHI_DEV_CTRL_RAM_DUMP: return "RAM_DUMP"; case MHI_DEV_CTRL_NOTIFY_LINK_ERROR: return "NOTIFY_LINK_ERROR"; default: return "UNKNOWN"; } }; static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) { int ret = 0; Loading Loading @@ -971,11 +1032,13 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, return 0; break; default: cnss_pr_err("Unhandled MHI DEV state (%d)\n", mhi_dev_state); cnss_pr_err("Unhandled MHI DEV state: %s(%d)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state); } cnss_pr_err("Cannot set MHI DEV state (%d) in current MHI state (0x%lx)\n", mhi_dev_state, pci_priv->mhi_state); cnss_pr_err("Cannot set MHI DEV state %s(%d) in current MHI state (0x%lx)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state, pci_priv->mhi_state); return -EINVAL; } Loading Loading @@ -1027,11 +1090,12 @@ int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, if (ret) goto out; cnss_pr_dbg("Setting MHI DEV state (%d)\n", mhi_dev_state); cnss_pr_dbg("Setting MHI DEV state: %s(%d)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state); ret = mhi_pm_control_device(&pci_priv->mhi_dev, mhi_dev_state); if (ret) { cnss_pr_err("Failed to set MHI DEV state (%d)\n", mhi_dev_state); cnss_pr_err("Failed to set MHI DEV state: %s(%d)\n", mhi_dev_state_to_str(mhi_dev_state), mhi_dev_state); goto out; } Loading Loading @@ -1197,6 +1261,8 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(&pci_dev->dev); cnss_pci_free_fw_mem(pci_priv); if (pci_dev->device == QCA6290_DEVICE_ID) { cnss_pci_unregister_mhi(pci_priv); cnss_pci_disable_msi(pci_priv); Loading
drivers/net/wireless/cnss2/pci.h +1 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,7 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); void cnss_pci_deinit(struct cnss_plat_data *plat_priv); int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv); int cnss_pci_get_bar_info(struct cnss_pci_data *pci_priv, void __iomem **va, phys_addr_t *pa); int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, Loading
drivers/net/wireless/cnss2/qmi.c +8 −26 Original line number Diff line number Diff line /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -257,15 +257,9 @@ int cnss_wlfw_respond_mem_send_sync(struct cnss_plat_data *plat_priv) cnss_pr_dbg("Sending respond memory message, state: 0x%lx\n", plat_priv->driver_state); if (!fw_mem->va && fw_mem->size) { fw_mem->va = dma_alloc_coherent(&plat_priv->plat_dev->dev, fw_mem->size, &fw_mem->pa, GFP_KERNEL); if (!fw_mem->va) { cnss_pr_err("Failed to allocate memory for FW, size: 0x%zx\n", fw_mem->size); fw_mem->size = 0; } if (!fw_mem->pa || !fw_mem->size) { cnss_pr_err("Memory for FW is not available!\n"); goto out; } cnss_pr_dbg("Memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n", Loading @@ -274,8 +268,8 @@ int cnss_wlfw_respond_mem_send_sync(struct cnss_plat_data *plat_priv) memset(&req, 0, sizeof(req)); memset(&resp, 0, sizeof(resp)); req.addr = plat_priv->fw_mem.pa; req.size = plat_priv->fw_mem.size; req.addr = fw_mem->pa; req.size = fw_mem->size; req_desc.max_msg_len = WLFW_RESPOND_MEM_REQ_MSG_V01_MAX_MSG_LEN; req_desc.msg_id = QMI_WLFW_RESPOND_MEM_REQ_V01; Loading Loading @@ -526,6 +520,7 @@ int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv, return 0; out: if (mode != QMI_WLFW_OFF_V01) CNSS_ASSERT(0); return ret; } Loading Loading @@ -676,8 +671,6 @@ err_create_handle: int cnss_wlfw_server_exit(struct cnss_plat_data *plat_priv) { struct cnss_fw_mem *fw_mem; if (!plat_priv) return -ENODEV; Loading @@ -685,17 +678,6 @@ int cnss_wlfw_server_exit(struct cnss_plat_data *plat_priv) clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); clear_bit(CNSS_QMI_WLFW_CONNECTED, &plat_priv->driver_state); fw_mem = &plat_priv->fw_mem; if (fw_mem->va && fw_mem->size) { cnss_pr_dbg("Freeing memory for FW, va: 0x%pK, pa: %pa, size: 0x%zx\n", fw_mem->va, &fw_mem->pa, fw_mem->size); dma_free_coherent(&plat_priv->plat_dev->dev, fw_mem->size, fw_mem->va, fw_mem->pa); fw_mem->va = NULL; fw_mem->pa = 0; fw_mem->size = 0; } cnss_pr_info("QMI WLFW service disconnected, state: 0x%lx\n", plat_priv->driver_state); Loading