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

Commit b11404df authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: save registers values in case of failure"

parents e0d22fe1 6fe52f68
Loading
Loading
Loading
Loading
+381 −41
Original line number Diff line number Diff line
@@ -37,9 +37,16 @@
			OFFLOAD_DRV_NAME " %s:%d " fmt, ## args); \
	} while (0)

#define IPA_WIGIG_RX_PIPE_IDX	0
#define IPA_WIGIG_TX_PIPE_NUM	4
#define IPA_WIGIG_MAX_PIPES	5

enum ipa_wigig_pipes_idx {
	IPA_CLIENT_WIGIG_PROD_IDX = 0,
	IPA_CLIENT_WIGIG1_CONS_IDX = 1,
	IPA_CLIENT_WIGIG2_CONS_IDX = 2,
	IPA_CLIENT_WIGIG3_CONS_IDX = 3,
	IPA_CLIENT_WIGIG4_CONS_IDX = 4,
	IPA_WIGIG_MAX_PIPES
};

struct ipa_wigig_intf_info {
	char netdev_name[IPA_RESOURCE_NAME_MAX];
@@ -49,6 +56,21 @@ struct ipa_wigig_intf_info {
	struct list_head link;
};

struct ipa_wigig_pipe_values {
	uint8_t dir;
	uint8_t tx_ring_id;
	uint32_t desc_ring_HWHEAD;
	uint32_t desc_ring_HWTAIL;
	uint32_t status_ring_HWHEAD;
	uint32_t status_ring_HWTAIL;
};

struct ipa_wigig_regs_save {
	struct ipa_wigig_pipe_values pipes_val[IPA_WIGIG_MAX_PIPES];
	u32 int_gen_tx_val;
	u32 int_gen_rx_val;
};

struct ipa_wigig_context {
	struct list_head head_intf_list;
	struct mutex lock;
@@ -58,14 +80,19 @@ struct ipa_wigig_context {
	phys_addr_t int_gen_tx_pa;
	phys_addr_t int_gen_rx_pa;
	phys_addr_t dma_ep_misc_pa;
	struct ipa_wigig_pipe_setup_info_smmu pipes_smmu[IPA_WIGIG_MAX_PIPES];
	union pipes {
		struct ipa_wigig_pipe_setup_info flat[IPA_WIGIG_MAX_PIPES];
		struct ipa_wigig_pipe_setup_info_smmu
			smmu[IPA_WIGIG_MAX_PIPES];
	} pipes;
	struct ipa_wigig_rx_pipe_data_buffer_info_smmu rx_buff_smmu;
	struct ipa_wigig_tx_pipe_data_buffer_info_smmu
		tx_buff_smmu[IPA_WIGIG_TX_PIPE_NUM];
	char clients_mac[IPA_WIGIG_TX_PIPE_NUM][IPA_MAC_ADDR_SIZE];
	struct ipa_wigig_regs_save regs_save;
	bool smmu_en;
	bool shared_cb;
	bool rx_connected;
	u8 conn_pipes;
};

static struct ipa_wigig_context *ipa_wigig_ctx;
@@ -557,6 +584,56 @@ static void ipa_wigig_pm_cb(void *p, enum ipa_pm_cb_event event)
	IPA_WIGIG_DBG("received pm event %d\n", event);
}

static int ipa_wigig_store_pipe_info(struct ipa_wigig_pipe_setup_info *pipe,
	unsigned int idx)
{
	IPA_WIGIG_DBG("\n");

	/* store regs */
	ipa_wigig_ctx->pipes.flat[idx].desc_ring_HWHEAD_pa =
		pipe->desc_ring_HWHEAD_pa;
	ipa_wigig_ctx->pipes.flat[idx].desc_ring_HWTAIL_pa =
		pipe->desc_ring_HWTAIL_pa;

	ipa_wigig_ctx->pipes.flat[idx].status_ring_HWHEAD_pa =
		pipe->status_ring_HWHEAD_pa;

	ipa_wigig_ctx->pipes.flat[idx].status_ring_HWTAIL_pa =
		pipe->status_ring_HWTAIL_pa;

	IPA_WIGIG_DBG("exit\n");

	return 0;
}

static u8 ipa_wigig_pipe_to_bit_val(int client)
{
	u8 shift_val;

	switch (client) {
	case IPA_CLIENT_WIGIG_PROD:
		shift_val = 0x1 << IPA_CLIENT_WIGIG_PROD_IDX;
		break;
	case IPA_CLIENT_WIGIG1_CONS:
		shift_val = 0x1 << IPA_CLIENT_WIGIG1_CONS_IDX;
		break;
	case IPA_CLIENT_WIGIG2_CONS:
		shift_val = 0x1 << IPA_CLIENT_WIGIG2_CONS_IDX;
		break;
	case IPA_CLIENT_WIGIG3_CONS:
		shift_val = 0x1 << IPA_CLIENT_WIGIG3_CONS_IDX;
		break;
	case IPA_CLIENT_WIGIG4_CONS:
		shift_val = 0x1 << IPA_CLIENT_WIGIG4_CONS_IDX;
		break;
	default:
		IPA_WIGIG_ERR("invalid pipe %d\n", client);
		return 1;
	}

	return shift_val;
}

int ipa_wigig_conn_rx_pipe(struct ipa_wigig_conn_rx_in_params *in,
	struct ipa_wigig_conn_out_params *out)
{
@@ -619,7 +696,11 @@ int ipa_wigig_conn_rx_pipe(struct ipa_wigig_conn_rx_in_params *in,
		goto fail_connect_pipe;
	}

	ipa_wigig_ctx->rx_connected = true;
	ipa_wigig_store_pipe_info(ipa_wigig_ctx->pipes.flat,
		IPA_CLIENT_WIGIG_PROD_IDX);

	ipa_wigig_ctx->conn_pipes |=
		ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD);

	IPA_WIGIG_DBG("exit\n");

@@ -663,7 +744,7 @@ static int ipa_wigig_client_to_idx(enum ipa_client_type client,
	return 0;
}

static int ipa_wigig_clean_pipe_smmu_info(unsigned int idx)
static int ipa_wigig_clean_pipe_info(unsigned int idx)
{
	IPA_WIGIG_DBG("cleaning pipe %d info\n", idx);

@@ -672,12 +753,19 @@ static int ipa_wigig_clean_pipe_smmu_info(unsigned int idx)
		return -EINVAL;
	}

	sg_free_table(&ipa_wigig_ctx->pipes_smmu[idx].desc_ring_base);
	sg_free_table(&ipa_wigig_ctx->pipes_smmu[idx].status_ring_base);
	if (ipa_wigig_ctx->smmu_en) {
		sg_free_table(
			&ipa_wigig_ctx->pipes.smmu[idx].desc_ring_base);
		sg_free_table(
			&ipa_wigig_ctx->pipes.smmu[idx].status_ring_base);

	memset(ipa_wigig_ctx->pipes_smmu + idx,
		memset(ipa_wigig_ctx->pipes.smmu + idx,
			0,
		sizeof(ipa_wigig_ctx->pipes_smmu[idx]));
			sizeof(ipa_wigig_ctx->pipes.smmu[idx]));
	} else {
		memset(ipa_wigig_ctx->pipes.flat + idx, 0,
			sizeof(ipa_wigig_ctx->pipes.flat[idx]));
	}

	IPA_WIGIG_DBG("exit\n");

@@ -713,30 +801,32 @@ static int ipa_wigig_store_pipe_smmu_info
	IPA_WIGIG_DBG("\n");

	/* store regs */
	ipa_wigig_ctx->pipes_smmu[idx].desc_ring_HWHEAD_pa =
	ipa_wigig_ctx->pipes.smmu[idx].desc_ring_HWHEAD_pa =
		pipe_smmu->desc_ring_HWHEAD_pa;
	ipa_wigig_ctx->pipes_smmu[idx].desc_ring_HWTAIL_pa =
	ipa_wigig_ctx->pipes.smmu[idx].desc_ring_HWTAIL_pa =
		pipe_smmu->desc_ring_HWTAIL_pa;

	ipa_wigig_ctx->pipes_smmu[idx].status_ring_HWHEAD_pa =
	ipa_wigig_ctx->pipes.smmu[idx].status_ring_HWHEAD_pa =
		pipe_smmu->status_ring_HWHEAD_pa;
	ipa_wigig_ctx->pipes_smmu[idx].status_ring_HWTAIL_pa =
	ipa_wigig_ctx->pipes.smmu[idx].status_ring_HWTAIL_pa =
		pipe_smmu->status_ring_HWTAIL_pa;

	/* store rings IOVAs */
	ipa_wigig_ctx->pipes_smmu[idx].desc_ring_base_iova =
	ipa_wigig_ctx->pipes.smmu[idx].desc_ring_base_iova =
		pipe_smmu->desc_ring_base_iova;
	ipa_wigig_ctx->pipes_smmu[idx].status_ring_base_iova =
	ipa_wigig_ctx->pipes.smmu[idx].status_ring_base_iova =
		pipe_smmu->status_ring_base_iova;

	/* copy sgt */
	ret = ipa_wigig_clone_sg_table(&pipe_smmu->desc_ring_base,
		&ipa_wigig_ctx->pipes_smmu[idx].desc_ring_base);
	ret = ipa_wigig_clone_sg_table(
		&pipe_smmu->desc_ring_base,
		&ipa_wigig_ctx->pipes.smmu[idx].desc_ring_base);
	if (ret)
		goto fail_desc;

	ret = ipa_wigig_clone_sg_table(&pipe_smmu->status_ring_base,
		&ipa_wigig_ctx->pipes_smmu[idx].status_ring_base);
	ret = ipa_wigig_clone_sg_table(
		&pipe_smmu->status_ring_base,
		&ipa_wigig_ctx->pipes.smmu[idx].status_ring_base);
	if (ret)
		goto fail_stat;

@@ -744,9 +834,9 @@ static int ipa_wigig_store_pipe_smmu_info

	return 0;
fail_stat:
	sg_free_table(&ipa_wigig_ctx->pipes_smmu[idx].desc_ring_base);
	memset(&ipa_wigig_ctx->pipes_smmu[idx].desc_ring_base,
		0, sizeof(ipa_wigig_ctx->pipes_smmu[idx].desc_ring_base));
	sg_free_table(&ipa_wigig_ctx->pipes.smmu[idx].desc_ring_base);
	memset(&ipa_wigig_ctx->pipes.smmu[idx].desc_ring_base, 0,
	       sizeof(ipa_wigig_ctx->pipes.smmu[idx].desc_ring_base));
fail_desc:
	return ret;
}
@@ -760,10 +850,238 @@ static int ipa_wigig_get_pipe_smmu_info(
		return -EINVAL;
	}

	*pipe_smmu = &ipa_wigig_ctx->pipes_smmu[idx];
	*pipe_smmu = &ipa_wigig_ctx->pipes.smmu[idx];

	return 0;
}

static int ipa_wigig_get_pipe_info(
	struct ipa_wigig_pipe_setup_info **pipe, unsigned int idx)
{
	if (idx >= IPA_WIGIG_MAX_PIPES) {
		IPA_WIGIG_ERR("exceeded pipe num %d >= %d\n", idx,
			IPA_WIGIG_MAX_PIPES);
		return -EINVAL;
	}

	*pipe = &ipa_wigig_ctx->pipes.flat[idx];

	return 0;
}

static int ipa_wigig_get_regs_addr(
	void __iomem **desc_ring_h, void __iomem **desc_ring_t,
	void __iomem **status_ring_h, void __iomem **status_ring_t,
	unsigned int idx)
{
	struct ipa_wigig_pipe_setup_info *pipe;
	struct ipa_wigig_pipe_setup_info_smmu *pipe_smmu;
	int ret = 0;

	IPA_WIGIG_DBG("\n");

	if (idx >= IPA_WIGIG_MAX_PIPES) {
		IPA_WIGIG_DBG("exceeded pipe num %d >= %d\n", idx,
			IPA_WIGIG_MAX_PIPES);
		return -EINVAL;
	}

	if (!ipa_wigig_ctx) {
		IPA_WIGIG_DBG("wigig ctx is not initialized\n");
		return -EPERM;
	}

	if (!(ipa_wigig_ctx->conn_pipes &
		ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD))) {
		IPA_WIGIG_DBG(
			"must connect rx pipe before connecting any client\n");
		return -EINVAL;
	}

	if (ipa_wigig_ctx->smmu_en) {
		ret = ipa_wigig_get_pipe_smmu_info(&pipe_smmu, idx);
		if (ret)
			return -EINVAL;

		*desc_ring_h =
			ioremap(pipe_smmu->desc_ring_HWHEAD_pa, sizeof(u32));
		if (!*desc_ring_h) {
			IPA_WIGIG_DBG(
				"couldn't ioremap desc ring head address\n");
			ret = -EINVAL;
			goto fail_map_desc_h;
		}
		*desc_ring_t =
			ioremap(pipe_smmu->desc_ring_HWTAIL_pa, sizeof(u32));
		if (!*desc_ring_t) {
			IPA_WIGIG_DBG(
				"couldn't ioremap desc ring tail address\n");
			ret = -EINVAL;
			goto fail_map_desc_t;
		}
		*status_ring_h =
			ioremap(pipe_smmu->status_ring_HWHEAD_pa, sizeof(u32));
		if (!*status_ring_h) {
			IPA_WIGIG_DBG(
				"couldn't ioremap status ring head address\n");
			ret = -EINVAL;
			goto fail_map_status_h;
		}
		*status_ring_t =
			ioremap(pipe_smmu->status_ring_HWTAIL_pa, sizeof(u32));
		if (!*status_ring_t) {
			IPA_WIGIG_DBG(
				"couldn't ioremap status ring tail address\n");
			ret = -EINVAL;
			goto fail_map_status_t;
		}
	} else {
		ret = ipa_wigig_get_pipe_info(&pipe, idx);
		if (ret)
			return -EINVAL;

		*desc_ring_h = ioremap(pipe->desc_ring_HWHEAD_pa, sizeof(u32));
		if (!*desc_ring_h) {
			IPA_WIGIG_DBG(
				"couldn't ioremap desc ring head address\n");
			ret = -EINVAL;
			goto fail_map_desc_h;
		}
		*desc_ring_t = ioremap(pipe->desc_ring_HWTAIL_pa, sizeof(u32));
		if (!*desc_ring_t) {
			IPA_WIGIG_DBG(
				"couldn't ioremap desc ring tail address\n");
			ret = -EINVAL;
			goto fail_map_desc_t;
		}
		*status_ring_h =
			ioremap(pipe->status_ring_HWHEAD_pa, sizeof(u32));
		if (!*status_ring_h) {
			IPA_WIGIG_DBG(
				"couldn't ioremap status ring head address\n");
			ret = -EINVAL;
			goto fail_map_status_h;
		}
		*status_ring_t =
			ioremap(pipe->status_ring_HWTAIL_pa, sizeof(u32));
		if (!*status_ring_t) {
			IPA_WIGIG_DBG(
				"couldn't ioremap status ring tail address\n");
			ret = -EINVAL;
			goto fail_map_status_t;
		}
	}

	IPA_WIGIG_DBG("exit\n");
	return 0;

fail_map_status_t:
	iounmap(*status_ring_h);
fail_map_status_h:
	iounmap(*desc_ring_t);
fail_map_desc_t:
	iounmap(*desc_ring_h);
fail_map_desc_h:
	IPA_WIGIG_DBG("couldn't get regs information idx %d\n", idx);
	return ret;
}

int ipa_wigig_save_regs(void)
{
	void __iomem *desc_ring_h = NULL, *desc_ring_t = NULL,
		*status_ring_h = NULL, *status_ring_t = NULL,
		*int_gen_rx_pa = NULL, *int_gen_tx_pa = NULL;
	uint32_t readval;
	u8 pipe_connected;
	int i, ret = 0;

	IPA_WIGIG_DBG("Start collecting pipes information\n");

	if (!ipa_wigig_ctx) {
		IPA_WIGIG_ERR("wigig ctx is not initialized\n");
		return -EPERM;
	}
	if (!(ipa_wigig_ctx->conn_pipes &
		ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD))) {
		IPA_WIGIG_ERR(
			"must connect rx pipe before connecting any client\n");
		return -EINVAL;
	}

	for (i = 0; i < IPA_WIGIG_MAX_PIPES; i++) {
		pipe_connected = (ipa_wigig_ctx->conn_pipes & (0x1 << i));
		if (pipe_connected) {
			ret = ipa_wigig_get_regs_addr(
				&desc_ring_h, &desc_ring_t,
				&status_ring_h, &status_ring_t, i);

			if (ret) {
				IPA_WIGIG_ERR(
					"couldn't get registers information on client %d\n",
					i);
				return -EINVAL;
			}

			IPA_WIGIG_DBG("collecting pipe info of index %d\n", i);
			if (i == IPA_CLIENT_WIGIG_PROD_IDX) {
				ipa_wigig_ctx->regs_save.pipes_val[i].dir = 0;
			} else {
				ipa_wigig_ctx->regs_save.pipes_val[i].dir = 1;
				/* TX ids start from 2 */
				ipa_wigig_ctx->regs_save.pipes_val[i]
					.tx_ring_id = i + 1;
			}

			readval = readl_relaxed(desc_ring_h);
			ipa_wigig_ctx->regs_save.pipes_val[i].desc_ring_HWHEAD =
				readval;
			readval = readl_relaxed(desc_ring_t);
			ipa_wigig_ctx->regs_save.pipes_val[i].desc_ring_HWTAIL =
				readval;
			readval = readl_relaxed(status_ring_h);
			ipa_wigig_ctx->regs_save.pipes_val[i]
				.status_ring_HWHEAD = readval;
			readval = readl_relaxed(status_ring_t);
			ipa_wigig_ctx->regs_save.pipes_val[i]
				.status_ring_HWTAIL = readval;
			/* unmap all regs */
			iounmap(desc_ring_h);
			iounmap(desc_ring_t);
			iounmap(status_ring_h);
			iounmap(status_ring_t);
		}
	}
	int_gen_rx_pa = ioremap(ipa_wigig_ctx->int_gen_rx_pa, sizeof(u32));
	if (!int_gen_rx_pa) {
		IPA_WIGIG_ERR("couldn't ioremap gen rx address\n");
		ret = -EINVAL;
		goto fail_map_gen_rx;
	}
	int_gen_tx_pa = ioremap(ipa_wigig_ctx->int_gen_tx_pa, sizeof(u32));
	if (!int_gen_tx_pa) {
		IPA_WIGIG_ERR("couldn't ioremap gen tx address\n");
		ret = -EINVAL;
		goto fail_map_gen_tx;
	}

	IPA_WIGIG_DBG("collecting int_gen_rx_pa info\n");
	readval = readl_relaxed(int_gen_rx_pa);
	ipa_wigig_ctx->regs_save.int_gen_rx_val = readval;

	IPA_WIGIG_DBG("collecting int_gen_tx_pa info\n");
	readval = readl_relaxed(int_gen_tx_pa);
	ipa_wigig_ctx->regs_save.int_gen_tx_val = readval;

	IPA_WIGIG_DBG("Finish collecting pipes info\n");
	IPA_WIGIG_DBG("exit\n");

	iounmap(int_gen_tx_pa);
fail_map_gen_tx:
	iounmap(int_gen_rx_pa);
fail_map_gen_rx:
	return ret;
}

static void ipa_wigig_clean_rx_buff_smmu_info(void)
{
	IPA_WIGIG_DBG("clearing rx buff smmu info\n");
@@ -774,9 +1092,6 @@ static void ipa_wigig_clean_rx_buff_smmu_info(void)
		sizeof(ipa_wigig_ctx->rx_buff_smmu));

	IPA_WIGIG_DBG("\n");

	return;

}

static int ipa_wigig_store_rx_buff_smmu_info(
@@ -926,7 +1241,7 @@ static int ipa_wigig_store_rx_smmu_info
	IPA_WIGIG_DBG("\n");

	ret = ipa_wigig_store_pipe_smmu_info(&in->pipe_smmu,
		IPA_WIGIG_RX_PIPE_IDX);
		IPA_CLIENT_WIGIG_PROD_IDX);
	if (ret)
		return ret;

@@ -941,7 +1256,7 @@ static int ipa_wigig_store_rx_smmu_info
	return 0;

fail_buff:
	ipa_wigig_clean_pipe_smmu_info(IPA_WIGIG_RX_PIPE_IDX);
	ipa_wigig_clean_pipe_info(IPA_CLIENT_WIGIG_PROD_IDX);
	return ret;
}

@@ -973,7 +1288,7 @@ static int ipa_wigig_store_client_smmu_info
	return 0;

fail_buff:
	ipa_wigig_clean_pipe_smmu_info(IPA_WIGIG_RX_PIPE_IDX);
	ipa_wigig_clean_pipe_info(IPA_CLIENT_WIGIG_PROD_IDX);
	return ret;
}

@@ -983,7 +1298,8 @@ static int ipa_wigig_get_rx_smmu_info(
{
	int ret;

	ret = ipa_wigig_get_pipe_smmu_info(pipe_smmu, IPA_WIGIG_RX_PIPE_IDX);
	ret = ipa_wigig_get_pipe_smmu_info(pipe_smmu,
		IPA_CLIENT_WIGIG_PROD_IDX);
	if (ret)
		return ret;

@@ -1022,7 +1338,7 @@ static int ipa_wigig_clean_smmu_info(enum ipa_client_type client)
	int ret;

	if (client == IPA_CLIENT_WIGIG_PROD) {
		ret = ipa_wigig_clean_pipe_smmu_info(IPA_WIGIG_RX_PIPE_IDX);
		ret = ipa_wigig_clean_pipe_info(IPA_CLIENT_WIGIG_PROD_IDX);
		if (ret)
			return ret;
		if (!ipa_wigig_ctx->shared_cb)
@@ -1034,7 +1350,7 @@ static int ipa_wigig_clean_smmu_info(enum ipa_client_type client)
		if (ret)
			return ret;

		ret = ipa_wigig_clean_pipe_smmu_info(idx);
		ret = ipa_wigig_clean_pipe_info(idx);
		if (ret)
			return ret;

@@ -1120,7 +1436,8 @@ int ipa_wigig_conn_rx_pipe_smmu(
		goto fail_smmu_store;
	}

	ipa_wigig_ctx->rx_connected = true;
	ipa_wigig_ctx->conn_pipes |=
		ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD);

	IPA_WIGIG_DBG("exit\n");

@@ -1201,6 +1518,7 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
	struct ipa_wigig_conn_out_params *out)
{
	char dev_name[IPA_RESOURCE_NAME_MAX];
	unsigned int idx;

	IPA_WIGIG_DBG("\n");

@@ -1214,7 +1532,8 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
		return -EPERM;
	}

	if (!ipa_wigig_ctx->rx_connected) {
	if (!(ipa_wigig_ctx->conn_pipes &
		ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD))) {
		IPA_WIGIG_ERR(
			"must connect rx pipe before connecting any client\n"
		);
@@ -1244,6 +1563,13 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
		return -EFAULT;
	}

	if (ipa_wigig_client_to_idx(out->client, &idx)) {
		IPA_WIGIG_ERR("couldn't acquire idx\n");
		goto fail_convert_client_to_idx;
	}

	ipa_wigig_store_pipe_info(&in->pipe, idx);

	if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT,
		dev_name,
		in->client_mac, out->client, false)) {
@@ -1251,13 +1577,20 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
		goto fail_sendmsg;
	}

	/* update connected clients */
	ipa_wigig_ctx->conn_pipes |=
		ipa_wigig_pipe_to_bit_val(out->client);

	ipa_wigig_store_client_mac(out->client, in->client_mac);

	IPA_WIGIG_DBG("exit\n");
	return 0;

fail_sendmsg:
	ipa_wigig_clean_pipe_info(idx);
fail_convert_client_to_idx:
	ipa_disconn_wigig_pipe_i(out->client, NULL, NULL);
	return -EFAULT;
	return -EINVAL;
}
EXPORT_SYMBOL(ipa_wigig_conn_client);

@@ -1280,7 +1613,8 @@ int ipa_wigig_conn_client_smmu(
		return -EPERM;
	}

	if (!ipa_wigig_ctx->rx_connected) {
	if (!(ipa_wigig_ctx->conn_pipes &
		ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD))) {
		IPA_WIGIG_ERR(
			"must connect rx pipe before connecting any client\n"
		);
@@ -1324,6 +1658,10 @@ int ipa_wigig_conn_client_smmu(
	if (ret)
		goto fail_smmu;

	/* update connected clients */
	ipa_wigig_ctx->conn_pipes |=
		ipa_wigig_pipe_to_bit_val(out->client);

	ipa_wigig_store_client_mac(out->client, in->client_mac);

	IPA_WIGIG_DBG("exit\n");
@@ -1439,7 +1777,9 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client)
			WARN_ON(1);
		}

		ipa_wigig_ctx->rx_connected = false;
		ipa_wigig_ctx->conn_pipes &=
			~ipa_wigig_pipe_to_bit_val(IPA_CLIENT_WIGIG_PROD);
		WARN_ON(ipa_wigig_ctx->conn_pipes);
	} else {
		/*
		 * wigig clients are disconnected with legacy message since
+2 −0
Original line number Diff line number Diff line
@@ -466,6 +466,8 @@ int ipa_wigig_send_msg(int msg_type,
	const char *netdev_name, u8 *mac,
	enum ipa_client_type client, bool to_wigig);

int ipa_wigig_save_regs(void);

void ipa_register_client_callback(int (*client_cb)(bool is_lock),
			bool (*teth_port_state)(void), u32 ipa_ep_idx);

+1 −0
Original line number Diff line number Diff line
@@ -5340,6 +5340,7 @@ static int ipa3_panic_notifier(struct notifier_block *this,
	if (atomic_read(&ipa3_ctx->ipa_clk_vote)) {
		ipahal_print_all_regs(false);
		ipa_save_registers();
		ipa_wigig_save_regs();
	}

	return NOTIFY_DONE;