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

Commit b4ea3e4d authored by Will Huang's avatar Will Huang
Browse files

cnss2: Add support for handling AFC memory request from FW



Add APIs for handling AFC memory request from FW:
cnss_send_buffer_to_afcmem() and cnss_reset_afcmem().

cnss_send_buffer_to_afcmem() will be called if receive valid AFC
response data, cnss_reset_afcmem() will be called if receive
invalid AFC response data. After memory copy done, another WMI
command will indicate FW ready to read.

Add FW memory type QMI_WLFW_AFC_MEM_V01.

Change-Id: I34b9add3d7721d778e5474d9b11ad64adb4f04f0
CRs-Fixed: 3223607
Signed-off-by: default avatarBalamurugan Mahalingam <bmahalin@codeaurora.org>
Signed-off-by: default avatarWill Huang <quic_wilhuang@quicinc.com>
parent f51d920c
Loading
Loading
Loading
Loading
+95 −0
Original line number Diff line number Diff line
@@ -89,6 +89,13 @@ static DEFINE_SPINLOCK(time_sync_lock);

#define MHI_SUSPEND_RETRY_CNT		3

#define AFC_SLOT_SIZE                   0x1000
#define AFC_MAX_SLOT                    2
#define AFC_MEM_SIZE                    (AFC_SLOT_SIZE * AFC_MAX_SLOT)
#define AFC_AUTH_STATUS_OFFSET          1
#define AFC_AUTH_SUCCESS                1
#define AFC_AUTH_ERROR                  0

static struct cnss_pci_reg ce_src[] = {
	{ "SRC_RING_BASE_LSB", QCA6390_CE_SRC_RING_BASE_LSB_OFFSET },
	{ "SRC_RING_BASE_MSB", QCA6390_CE_SRC_RING_BASE_MSB_OFFSET },
@@ -3977,6 +3984,94 @@ int cnss_pci_qmi_send_put(struct cnss_pci_data *pci_priv)
	return ret;
}

int cnss_send_buffer_to_afcmem(struct device *dev, char *afcdb, uint32_t len,
			       uint8_t slotid)
{
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
	struct cnss_fw_mem *fw_mem;
	void *mem = NULL;
	int i, ret;
	u32 *status;

	if (!plat_priv)
		return -EINVAL;

	fw_mem = plat_priv->fw_mem;
	if (slotid >= AFC_MAX_SLOT) {
		cnss_pr_err("Invalid slot id %d\n", slotid);
		ret = -EINVAL;
		goto err;
	}
	if (len > AFC_SLOT_SIZE) {
		cnss_pr_err("len %d greater than slot size", len);
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < plat_priv->fw_mem_seg_len; i++) {
		if (fw_mem[i].type == QMI_WLFW_AFC_MEM_V01) {
			mem = fw_mem[i].va;
			status = mem + (slotid * AFC_SLOT_SIZE);
			break;
		}
	}

	if (!mem) {
		cnss_pr_err("AFC mem is not available\n");
		ret = -ENOMEM;
		goto err;
	}

	memcpy(mem + (slotid * AFC_SLOT_SIZE), afcdb, len);
	if (len < AFC_SLOT_SIZE)
		memset(mem + (slotid * AFC_SLOT_SIZE) + len,
		       0, AFC_SLOT_SIZE - len);
	status[AFC_AUTH_STATUS_OFFSET] = cpu_to_le32(AFC_AUTH_SUCCESS);

	return 0;
err:
	return ret;
}
EXPORT_SYMBOL(cnss_send_buffer_to_afcmem);

int cnss_reset_afcmem(struct device *dev, uint8_t slotid)
{
	struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
	struct cnss_fw_mem *fw_mem;
	void *mem = NULL;
	int i, ret;

	if (!plat_priv)
		return -EINVAL;

	fw_mem = plat_priv->fw_mem;
	if (slotid >= AFC_MAX_SLOT) {
		cnss_pr_err("Invalid slot id %d\n", slotid);
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < plat_priv->fw_mem_seg_len; i++) {
		if (fw_mem[i].type == QMI_WLFW_AFC_MEM_V01) {
			mem = fw_mem[i].va;
			break;
		}
	}

	if (!mem) {
		cnss_pr_err("AFC mem is not available\n");
		ret = -ENOMEM;
		goto err;
	}

	memset(mem + (slotid * AFC_SLOT_SIZE), 0, AFC_SLOT_SIZE);
	return 0;

err:
	return ret;
}
EXPORT_SYMBOL(cnss_reset_afcmem);

int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv)
{
	struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ enum wlfw_mem_type_enum_v01 {
	QMI_WLFW_MEM_HANG_DATA_V01 = 7,
	QMI_WLFW_MLO_GLOBAL_MEM_V01 = 8,
	QMI_WLFW_PAGEABLE_MEM_V01 = 9,
	QMI_WLFW_AFC_MEM_V01 = 10,
	WLFW_MEM_TYPE_ENUM_MAX_VAL_V01 = INT_MAX,
};

+3 −0
Original line number Diff line number Diff line
@@ -278,4 +278,7 @@ extern int cnss_get_mem_seg_count(enum cnss_remote_mem_type type, u32 *seg);
extern int cnss_get_mem_segment_info(enum cnss_remote_mem_type type,
				     struct cnss_mem_segment segment[],
				     u32 segment_count);
extern int cnss_send_buffer_to_afcmem(struct device *dev, char *afcdb,
				      uint32_t len, uint8_t slotid);
extern int cnss_reset_afcmem(struct device *dev, uint8_t slotid);
#endif /* _NET_CNSS2_H */