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

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

Merge "msm: ipa: Set ep delay on rmnet/mbim tether pipe"

parents 1e8f3ad2 78a2a6f4
Loading
Loading
Loading
Loading
+58 −3
Original line number Original line Diff line number Diff line
@@ -1351,6 +1351,7 @@ int ipa3_set_usb_max_packet_size(
	return 0;
	return 0;
}
}


/* This function called as part of usb pipe resume */
int ipa3_xdci_connect(u32 clnt_hdl)
int ipa3_xdci_connect(u32 clnt_hdl)
{
{
	int result;
	int result;
@@ -1390,11 +1391,14 @@ exit:
	return result;
	return result;
}
}



/* This function called as part of usb pipe connect */
int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid)
int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid)
{
{
	struct ipa3_ep_context *ep;
	struct ipa3_ep_context *ep;
	int result = -EFAULT;
	int result = -EFAULT;
	enum gsi_status gsi_res;
	enum gsi_status gsi_res;
	struct ipa_ep_cfg_ctrl ep_cfg_ctrl;


	IPADBG("entry\n");
	IPADBG("entry\n");
	if (clnt_hdl >= ipa3_ctx->ipa_num_pipes  ||
	if (clnt_hdl >= ipa3_ctx->ipa_num_pipes  ||
@@ -1416,6 +1420,22 @@ int ipa3_xdci_start(u32 clnt_hdl, u8 xferrscidx, bool xferrscidx_valid)
			goto write_chan_scratch_fail;
			goto write_chan_scratch_fail;
		}
		}
	}
	}

	if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) {
		memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
		ep_cfg_ctrl.ipa_ep_delay = true;
		ep->ep_delay_set = true;

		result = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);
		if (result)
			IPAERR("client (ep: %d) failed result=%d\n",
			clnt_hdl, result);
		else
			IPADBG("client (ep: %d) success\n", clnt_hdl);
	} else {
		ep->ep_delay_set = false;
	}

	gsi_res = gsi_start_channel(ep->gsi_chan_hdl);
	gsi_res = gsi_start_channel(ep->gsi_chan_hdl);
	if (gsi_res != GSI_STATUS_SUCCESS) {
	if (gsi_res != GSI_STATUS_SUCCESS) {
		IPAERR("Error starting channel: %d\n", gsi_res);
		IPAERR("Error starting channel: %d\n", gsi_res);
@@ -1620,13 +1640,15 @@ static int ipa3_xdci_stop_gsi_ch_brute_force(u32 clnt_hdl,


/* Clocks should be voted for before invoking this function */
/* Clocks should be voted for before invoking this function */
static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id,
static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id,
		u32 source_pipe_bitmask, bool should_force_clear, u32 clnt_hdl)
		u32 source_pipe_bitmask, bool should_force_clear, u32 clnt_hdl,
		bool remove_delay)
{
{
	int result;
	int result;
	bool is_empty = false;
	bool is_empty = false;
	int i;
	int i;
	bool stop_in_proc;
	bool stop_in_proc;
	struct ipa3_ep_context *ep;
	struct ipa3_ep_context *ep;
	struct ipa_ep_cfg_ctrl ep_cfg_ctrl;


	if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
	if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
		ipa3_ctx->ep[clnt_hdl].valid == 0) {
		ipa3_ctx->ep[clnt_hdl].valid == 0) {
@@ -1647,6 +1669,22 @@ static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id,
	if (!stop_in_proc)
	if (!stop_in_proc)
			goto exit;
			goto exit;


	if (remove_delay && ep->ep_delay_set == true) {
		memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
		ep_cfg_ctrl.ipa_ep_delay = false;
		result = ipa3_cfg_ep_ctrl(clnt_hdl,
			&ep_cfg_ctrl);
		if (result) {
			IPAERR
			("client (ep: %d) failed to remove delay result=%d\n",
				clnt_hdl, result);
		} else {
			IPADBG("client (ep: %d) delay removed\n",
				clnt_hdl);
			ep->ep_delay_set = false;
		}
	}

	/* if stop_in_proc, lets wait for emptiness */
	/* if stop_in_proc, lets wait for emptiness */
	for (i = 0; i < IPA_POLL_FOR_EMPTINESS_NUM; i++) {
	for (i = 0; i < IPA_POLL_FOR_EMPTINESS_NUM; i++) {
		result = ipa3_is_xdci_channel_empty(ep, &is_empty);
		result = ipa3_is_xdci_channel_empty(ep, &is_empty);
@@ -1712,6 +1750,21 @@ disable_force_clear_and_exit:
	if (should_force_clear)
	if (should_force_clear)
		ipa3_disable_force_clear(qmi_req_id);
		ipa3_disable_force_clear(qmi_req_id);
exit:
exit:
	if (remove_delay && ep->ep_delay_set == true) {
		memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
		ep_cfg_ctrl.ipa_ep_delay = false;
		result = ipa3_cfg_ep_ctrl(clnt_hdl,
			&ep_cfg_ctrl);
		if (result) {
			IPAERR
			("client (ep: %d) failed to remove delay result=%d\n",
				clnt_hdl, result);
		} else {
			IPADBG("client (ep: %d) delay removed\n",
				clnt_hdl);
			ep->ep_delay_set = false;
		}
	}
	return result;
	return result;
}
}


@@ -1741,7 +1794,8 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id)
		source_pipe_bitmask = 1 <<
		source_pipe_bitmask = 1 <<
			ipa3_get_ep_mapping(ep->client);
			ipa3_get_ep_mapping(ep->client);
		result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id,
		result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id,
			source_pipe_bitmask, should_force_clear, clnt_hdl);
			source_pipe_bitmask, should_force_clear, clnt_hdl,
			true);
		if (result) {
		if (result) {
			IPAERR("Fail to stop UL channel with data drain\n");
			IPAERR("Fail to stop UL channel with data drain\n");
			BUG();
			BUG();
@@ -1916,7 +1970,8 @@ int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
	if (!is_dpl) {
	if (!is_dpl) {
		source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ul_ep->client);
		source_pipe_bitmask = 1 << ipa3_get_ep_mapping(ul_ep->client);
		result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id,
		result = ipa3_stop_ul_chan_with_data_drain(qmi_req_id,
			source_pipe_bitmask, should_force_clear, ul_clnt_hdl);
			source_pipe_bitmask, should_force_clear, ul_clnt_hdl,
			false);
		if (result) {
		if (result) {
			IPAERR("Error stopping UL channel: result = %d\n",
			IPAERR("Error stopping UL channel: result = %d\n",
				result);
				result);
+1 −0
Original line number Original line Diff line number Diff line
@@ -610,6 +610,7 @@ struct ipa3_ep_context {
	u32 uc_offload_state;
	u32 uc_offload_state;
	bool disconnect_in_progress;
	bool disconnect_in_progress;
	u32 qmi_request_sent;
	u32 qmi_request_sent;
	bool ep_delay_set;


	/* sys MUST be the last element of this struct */
	/* sys MUST be the last element of this struct */
	struct ipa3_sys_context *sys;
	struct ipa3_sys_context *sys;