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

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

Merge "msm: ipa4: Cleanup duplicate code used for setup coalescing pipe"

parents 8a00176a 1e7bf8cc
Loading
Loading
Loading
Loading
+16 −193
Original line number Diff line number Diff line
@@ -111,8 +111,6 @@ static int ipa_gsi_setup_event_ring(struct ipa3_ep_context *ep,
	u32 ring_size, gfp_t mem_flag);
static int ipa_gsi_setup_transfer_ring(struct ipa3_ep_context *ep,
	u32 ring_size, struct ipa3_sys_context *user_data, gfp_t mem_flag);
static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in,
	struct ipa3_ep_context *ep_coalescing);
static int ipa3_teardown_coal_def_pipe(u32 clnt_hdl);
static int ipa_populate_tag_field(struct ipa3_desc *desc,
		struct ipa3_tx_pkt_wrapper *tx_pkt,
@@ -911,7 +909,7 @@ static void ipa_pm_sys_pipe_cb(void *p, enum ipa_pm_cb_event event)
int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
{
	struct ipa3_ep_context *ep;
	int i, ipa_ep_idx;
	int i, ipa_ep_idx, wan_handle;
	int result = -EINVAL;
	struct ipahal_reg_coal_qmap_cfg qmap_cfg;
	struct ipahal_reg_coal_evict_lru evict_lru;
@@ -1148,7 +1146,7 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)

		sys_in->client = IPA_CLIENT_APPS_WAN_CONS;
		sys_in->ipa_ep_cfg = ep_cfg_copy;
		result = ipa_setup_coal_def_pipe(sys_in, ep);
		result = ipa3_setup_sys_pipe(sys_in, &wan_handle);
		if (result) {
			IPAERR("failed to setup default coalescing pipe\n");
			goto fail_repl;
@@ -1178,193 +1176,6 @@ int ipa3_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl)
	return result;
}

/**
 * ipa3_setup_coal_def_pipe() - Setup a crippled default pipe in addition to the
 * coalescing pipe.
 *
 * @sys_in:	[in] input needed to setup the pipe and configure EP
 * @ep_coalescing [in] the ep context of the coal pipe
 *
 *  - configure the end-point registers with the supplied
 *    parameters from the user.
 *  - Creates a GPI connection with IPA.
 *  - allocate descriptor FIFO
 *
 * Returns:	0 on success, negative on failure
 */
static int ipa_setup_coal_def_pipe(struct ipa_sys_connect_params *sys_in,
	struct ipa3_ep_context *ep_coalescing)
{
	struct ipa3_ep_context *ep;
	int result = -EINVAL;
	int ipa_ep_idx, i;
	char buff[IPA_RESOURCE_NAME_MAX];

	ipa_ep_idx = ipa3_get_ep_mapping(sys_in->client);

	if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED) {
		IPAERR("failed to get idx");
		goto fail_gen;
	}

	ep = &ipa3_ctx->ep[ipa_ep_idx];
	if (ep->valid == 1) {
		IPAERR("EP %d already allocated.\n", ipa_ep_idx);
		goto fail_gen;
	}

	memset(ep, 0, offsetof(struct ipa3_ep_context, sys));

	if (!ep->sys) {
		ep->sys = kzalloc(sizeof(struct ipa3_sys_context), GFP_KERNEL);
		if (!ep->sys) {
			IPAERR("failed to sys ctx for client %d\n",
				IPA_CLIENT_APPS_WAN_CONS);
			result = -ENOMEM;
			goto fail_gen;
		}

		ep->sys->ep = ep;
		snprintf(buff, IPA_RESOURCE_NAME_MAX, "ipawq%d",
				sys_in->client);
		ep->sys->wq = alloc_workqueue(buff,
				WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1);

		if (!ep->sys->wq) {
			IPAERR("failed to create wq for client %d\n",
					sys_in->client);
			result = -EFAULT;
			goto fail_wq;
		}

		snprintf(buff, IPA_RESOURCE_NAME_MAX, "iparepwq%d",
				sys_in->client);
		ep->sys->repl_wq = alloc_workqueue(buff,
				WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_SYSFS, 1);
		if (!ep->sys->repl_wq) {
			IPAERR("failed to create rep wq for client %d\n",
					sys_in->client);
			result = -EFAULT;
			goto fail_wq2;
		}

		INIT_LIST_HEAD(&ep->sys->rcycl_list);
		spin_lock_init(&ep->sys->spinlock);
		hrtimer_init(&ep->sys->db_timer, CLOCK_MONOTONIC,
			HRTIMER_MODE_REL);
		ep->sys->db_timer.function = ipa3_ring_doorbell_timer_fn;
	} else {
		memset(ep->sys, 0, offsetof(struct ipa3_sys_context, ep));
	}

	ep->skip_ep_cfg = ep_coalescing->skip_ep_cfg;

	if (ipa3_assign_policy(sys_in, ep->sys)) {
		IPAERR("failed to sys ctx for client %d\n",
			IPA_CLIENT_APPS_WAN_CONS);
		result = -ENOMEM;
		goto fail_gen2;
	}

	ep->valid = 1;
	ep->client = sys_in->client;
	ep->client_notify = ep_coalescing->client_notify;
	ep->priv = ep_coalescing->priv;
	ep->keep_ipa_awake = ep_coalescing->keep_ipa_awake;
	atomic_set(&ep->avail_fifo_desc,
		((sys_in->desc_fifo_sz / IPA_FIFO_ELEMENT_SIZE) - 1));

	if (!ep->skip_ep_cfg) {
		if (ipa3_cfg_ep(ipa_ep_idx, &sys_in->ipa_ep_cfg)) {
			IPAERR("fail to configure EP.\n");
			goto fail_gen2;
		}

		if (ep->status.status_en) {
			IPAERR("status should be disabled for this EP.\n");
			goto fail_gen2;
		}

		if (ipa3_cfg_ep_status(ipa_ep_idx, &ep->status)) {
			IPAERR("fail to configure status of EP.\n");
			goto fail_gen2;
		}
		IPADBG("ep %d configuration successful\n", ipa_ep_idx);
	} else {
		IPADBG("skipping ep %d configuration\n", ipa_ep_idx);
	}

	result = ipa_gsi_setup_coal_def_channel(sys_in, ep, ep_coalescing);
	if (result) {
		IPAERR("Failed to setup default coal GSI channel\n");
		goto fail_gen2;
	}

	if (ep->sys->repl_hdlr == ipa3_fast_replenish_rx_cache) {
		ep->sys->repl = kzalloc(sizeof(*ep->sys->repl), GFP_KERNEL);
		if (!ep->sys->repl) {
			IPAERR("failed to alloc repl for client %d\n",
					sys_in->client);
			result = -ENOMEM;
			goto fail_gen2;
		}
		atomic_set(&ep->sys->repl->pending, 0);
		ep->sys->repl->capacity = ep->sys->rx_pool_sz + 1;

		ep->sys->repl->cache = kcalloc(ep->sys->repl->capacity,
				sizeof(void *), GFP_KERNEL);
		if (!ep->sys->repl->cache) {
			IPAERR("ep=%d fail to alloc repl cache\n", ipa_ep_idx);
			ep->sys->repl_hdlr = ipa3_replenish_rx_cache;
			ep->sys->repl->capacity = 0;
		} else {
			atomic_set(&ep->sys->repl->head_idx, 0);
			atomic_set(&ep->sys->repl->tail_idx, 0);
			ipa3_wq_repl_rx(&ep->sys->repl_work);
		}
	}

	ipa3_replenish_rx_cache(ep->sys);

	for (i = 0; i < GSI_VEID_MAX; i++)
		INIT_LIST_HEAD(&ep->sys->pending_pkts[i]);

	ipa3_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg;

	result = ipa3_enable_data_path(ipa_ep_idx);
	if (result) {
		IPAERR("enable data path failed res=%d ep=%d.\n", result,
			ipa_ep_idx);
		goto fail_repl;
	}

	result = gsi_start_channel(ep->gsi_chan_hdl);
	if (result != GSI_STATUS_SUCCESS)
		goto fail_start_channel;

	IPADBG("client %d (ep: %d) connected sys=%pK\n", ep->client,
			ipa_ep_idx, ep->sys);

	return 0;

/* the rest of the fails are handled by ipa3_setup_sys_pipe */
fail_start_channel:
	ipa3_disable_data_path(ipa_ep_idx);
fail_repl:
	ep->sys->repl_hdlr = ipa3_replenish_rx_cache;
	ep->sys->repl->capacity = 0;
	kfree(ep->sys->repl);
fail_gen2:
	destroy_workqueue(ep->sys->repl_wq);
fail_wq2:
	destroy_workqueue(ep->sys->wq);
fail_wq:
	kfree(ep->sys);
	memset(&ipa3_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa3_ep_context));
fail_gen:
	return result;
}

/**
 * ipa3_teardown_sys_pipe() - Teardown the GPI pipe and cleanup IPA EP
 * @clnt_hdl:	[in] the handle obtained from ipa3_setup_sys_pipe
@@ -4087,7 +3898,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
	u32 ring_size;
	int result;
	gfp_t mem_flag = GFP_KERNEL;

	u32 coale_ep_idx;

	if (in->client == IPA_CLIENT_APPS_WAN_CONS ||
		in->client == IPA_CLIENT_APPS_WAN_COAL_CONS ||
@@ -4098,6 +3909,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
		IPAERR("EP context is empty\n");
		return -EINVAL;
	}
	coale_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS);
	/*
	 * GSI ring length is calculated based on the desc_fifo_sz
	 * which was meant to define the BAM desc fifo. GSI descriptors
@@ -4116,6 +3928,17 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
		}
		ipa3_ctx->gsi_evt_comm_ring_rem -= (ring_size);
		ep->gsi_evt_ring_hdl = ipa3_ctx->gsi_evt_comm_hdl;
	} else if (in->client == IPA_CLIENT_APPS_WAN_CONS &&
			coale_ep_idx != IPA_EP_NOT_ALLOCATED &&
			ipa3_ctx->ep[coale_ep_idx].valid == 1) {
		IPADBG("Wan consumer pipe configured\n");
		result = ipa_gsi_setup_coal_def_channel(in, ep,
					&ipa3_ctx->ep[coale_ep_idx]);
		if (result) {
			IPAERR("Failed to setup default coal GSI channel\n");
			goto fail_setup_event_ring;
		}
		return result;
	} else if (ep->sys->policy != IPA_POLICY_NOINTR_MODE ||
			IPA_CLIENT_IS_CONS(ep->client)) {
		result = ipa_gsi_setup_event_ring(ep, ring_size, mem_flag);