Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9411e4e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: Do not assert if mode off QMI message fails"

parents f64c5593 c381ab72
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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:
+72 −6
Original line number Diff line number Diff line
@@ -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)
{
@@ -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;
@@ -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;
}
@@ -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;
	}

@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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,
+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
@@ -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",
@@ -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;
@@ -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;
}
@@ -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;

@@ -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);