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

Commit 2002720e 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: Add support for RNDIS flow control."

parents 326a2864 175aa199
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -278,6 +278,51 @@ static int ipa_open(struct inode *inode, struct file *filp)
	return 0;
}

/**
* ipa_flow_control() - Enable/Disable flow control on a particular client.
* Return codes:
* None
*/
void ipa_flow_control(enum ipa_client_type ipa_client,
		bool enable, uint32_t qmap_id)
{
	struct ipa_ep_cfg_ctrl ep_ctrl = {0};
	int ep_idx;
	struct ipa_ep_context *ep;

	/* Check if ep is valid. */
	ep_idx = ipa2_get_ep_mapping(ipa_client);
	if (ep_idx == -1) {
		IPAERR("Invalid IPA client\n");
		return;
	}

	ep = &ipa_ctx->ep[ep_idx];
	if (!ep->valid) {
		IPAERR("EP not valid.\n");
		return;
	}

	/* Check if the QMAP_ID matches. */
	if (ep->cfg.meta.qmap_id != qmap_id) {
		IPADBG("Flow control indication not for the same flow: %u %u\n",
			ep->cfg.meta.qmap_id, qmap_id);
		return;
	}

	if (enable) {
		IPADBG("Enabling Flow\n");
		ep_ctrl.ipa_ep_delay = false;
		IPA_STATS_INC_CNT(ipa_ctx->stats.flow_enable);
	} else {
		IPADBG("Disabling Flow\n");
		ep_ctrl.ipa_ep_delay = true;
		IPA_STATS_INC_CNT(ipa_ctx->stats.flow_disable);
	}
	ep_ctrl.ipa_ep_suspend = false;
	ipa2_cfg_ep_ctrl(ep_idx, &ep_ctrl);
}

static void ipa_wan_msg_free_cb(void *buff, u32 len, u32 type)
{
	if (!buff) {
+6 −2
Original line number Diff line number Diff line
@@ -866,7 +866,9 @@ static ssize_t ipa_read_stats(struct file *file, char __user *ubuf,
			"wan_rx_empty=%u\n"
			"wan_repl_rx_empty=%u\n"
			"lan_rx_empty=%u\n"
			"lan_repl_rx_empty=%u\n",
			"lan_repl_rx_empty=%u\n"
			"flow_enable=%u\n"
			"flow_disable=%u\n",
			ipa_ctx->stats.tx_sw_pkts,
			ipa_ctx->stats.tx_hw_pkts,
			ipa_ctx->stats.tx_pkts_compl,
@@ -879,7 +881,9 @@ static ssize_t ipa_read_stats(struct file *file, char __user *ubuf,
			ipa_ctx->stats.wan_rx_empty,
			ipa_ctx->stats.wan_repl_rx_empty,
			ipa_ctx->stats.lan_rx_empty,
			ipa_ctx->stats.lan_repl_rx_empty);
			ipa_ctx->stats.lan_repl_rx_empty,
			ipa_ctx->stats.flow_enable,
			ipa_ctx->stats.flow_disable);
		cnt += nbytes;

		for (i = 0; i < MAX_NUM_EXCP; i++) {
+4 −0
Original line number Diff line number Diff line
@@ -763,6 +763,8 @@ struct ipa_stats {
	u32 wan_repl_rx_empty;
	u32 lan_rx_empty;
	u32 lan_repl_rx_empty;
	u32 flow_enable;
	u32 flow_disable;
};

struct ipa_active_clients {
@@ -1961,4 +1963,6 @@ int ipa2_release_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info);
int ipa2_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info);
void ipa_suspend_apps_pipes(bool suspend);
void ipa_update_repl_threshold(enum ipa_client_type ipa_client);
void ipa_flow_control(enum ipa_client_type ipa_client, bool enable,
			uint32_t qmap_id);
#endif /* _IPA_I_H_ */
+16 −0
Original line number Diff line number Diff line
@@ -1220,9 +1220,25 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
		break;
	/*  Flow enable  */
	case RMNET_IOCTL_FLOW_ENABLE:
		IPAWANDBG("Received flow enable\n");
		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
			sizeof(struct rmnet_ioctl_data_s))) {
			rc = -EFAULT;
			break;
		}
		ipa_flow_control(IPA_CLIENT_USB_PROD, true,
			ioctl_data.u.tcm_handle);
		break;
	/*  Flow disable  */
	case RMNET_IOCTL_FLOW_DISABLE:
		IPAWANDBG("Received flow disable\n");
		if (copy_from_user(&ioctl_data, ifr->ifr_ifru.ifru_data,
			sizeof(struct rmnet_ioctl_data_s))) {
			rc = -EFAULT;
			break;
		}
		ipa_flow_control(IPA_CLIENT_USB_PROD, false,
			ioctl_data.u.tcm_handle);
		break;
	/*  Set flow handle  */
	case RMNET_IOCTL_FLOW_SET_HNDL:
+45 −0
Original line number Diff line number Diff line
@@ -277,6 +277,51 @@ static int ipa3_open(struct inode *inode, struct file *filp)
	return 0;
}

/**
* ipa3_flow_control() - Enable/Disable flow control on a particular client.
* Return codes:
* None
*/
void ipa3_flow_control(enum ipa_client_type ipa_client,
		bool enable, uint32_t qmap_id)
{
	struct ipa_ep_cfg_ctrl ep_ctrl = {0};
	int ep_idx;
	struct ipa3_ep_context *ep;

	/* Check if ep is valid. */
	ep_idx = ipa3_get_ep_mapping(ipa_client);
	if (ep_idx == -1) {
		IPAERR("Invalid IPA client\n");
		return;
	}

	ep = &ipa3_ctx->ep[ep_idx];
	if (!ep->valid) {
		IPAERR("EP not valid.\n");
		return;
	}

	/* Check if the QMAP_ID matches. */
	if (ep->cfg.meta.qmap_id != qmap_id) {
		IPADBG("Flow control indication not for the same flow: %u %u\n",
			ep->cfg.meta.qmap_id, qmap_id);
		return;
	}

	if (enable) {
		IPADBG("Enabling Flow\n");
		ep_ctrl.ipa_ep_delay = false;
		IPA_STATS_INC_CNT(ipa3_ctx->stats.flow_enable);
	} else {
		IPADBG("Disabling Flow\n");
		ep_ctrl.ipa_ep_delay = true;
		IPA_STATS_INC_CNT(ipa3_ctx->stats.flow_disable);
	}
	ep_ctrl.ipa_ep_suspend = false;
	ipa3_cfg_ep_ctrl(ep_idx, &ep_ctrl);
}

static void ipa3_wan_msg_free_cb(void *buff, u32 len, u32 type)
{
	if (!buff) {
Loading