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

Commit 8a8fb3f1 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 new IOCTL to modify routing rule given its handle"

parents 7833e078 dfa352e2
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -160,6 +160,9 @@
#define IPA_IOC_DEL_HDR_PROC_CTX32 _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_DEL_HDR_PROC_CTX, \
				compat_uptr_t)
#define IPA_IOC_MDFY_RT_RULE32 _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_MDFY_RT_RULE, \
				compat_uptr_t)

/**
 * struct ipa_ioc_nat_alloc_mem32 - nat table memory allocation
@@ -443,6 +446,35 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
		}
		break;

	case IPA_IOC_MDFY_RT_RULE:
		if (copy_from_user(header, (u8 *)arg,
					sizeof(struct ipa_ioc_mdfy_rt_rule))) {
			retval = -EFAULT;
			break;
		}
		pyld_sz =
		   sizeof(struct ipa_ioc_mdfy_rt_rule) +
		   ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules *
		   sizeof(struct ipa_rt_rule_mdfy);
		param = kzalloc(pyld_sz, GFP_KERNEL);
		if (!param) {
			retval = -ENOMEM;
			break;
		}
		if (copy_from_user(param, (u8 *)arg, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		if (ipa_mdfy_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) {
			retval = -EFAULT;
			break;
		}
		if (copy_to_user((u8 *)arg, param, pyld_sz)) {
			retval = -EFAULT;
			break;
		}
		break;

	case IPA_IOC_DEL_RT_RULE:
		if (copy_from_user(header, (u8 *)arg,
					sizeof(struct ipa_ioc_del_rt_rule))) {
@@ -2192,6 +2224,9 @@ ret:
	case IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED32:
		cmd = IPA_IOC_NOTIFY_WAN_EMBMS_CONNECTED;
		break;
	case IPA_IOC_MDFY_RT_RULE32:
		cmd = IPA_IOC_MDFY_RT_RULE;
		break;
	case IPA_IOC_COMMIT_HDR:
	case IPA_IOC_RESET_HDR:
	case IPA_IOC_COMMIT_RT:
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ const char *ipa_event_name[] = {
	__stringify(WLAN_STA_CONNECT),
	__stringify(WLAN_STA_DISCONNECT),
	__stringify(WLAN_CLIENT_CONNECT_EX),
	__stringify(WLAN_SWITCH_TO_SCC),
	__stringify(WLAN_SWITCH_TO_MCC),
	__stringify(WAN_UPSTREAM_ROUTE_ADD),
	__stringify(WAN_UPSTREAM_ROUTE_DEL),
	__stringify(WAN_EMBMS_CONNECT),
+82 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#define IPA_RT_BIT_MASK			(0x1)
#define IPA_RT_STATUS_OF_ADD_FAILED	(-1)
#define IPA_RT_STATUS_OF_DEL_FAILED	(-1)
#define IPA_RT_STATUS_OF_MDFY_FAILED (-1)

/**
 * __ipa_generate_rt_hw_rule_v2() - generates the routing hardware rule
@@ -1337,3 +1338,84 @@ ret:
	return result;
}
EXPORT_SYMBOL(ipa_put_rt_tbl);


static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
{
	struct ipa_rt_entry *entry;
	struct ipa_hdr_entry *hdr = NULL;

	if (rtrule->rule.hdr_hdl) {
		hdr = ipa_id_find(rtrule->rule.hdr_hdl);
		if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
			IPAERR("rt rule does not point to valid hdr\n");
			goto error;
		}
	}

	entry = ipa_id_find(rtrule->rt_rule_hdl);
	if (entry == NULL) {
		IPAERR("lookup failed\n");
		goto error;
	}

	if (entry->cookie != IPA_COOKIE) {
		IPAERR("bad params\n");
		goto error;
	}

	if (entry->hdr)
		entry->hdr->ref_cnt--;

	entry->rule = rtrule->rule;
	entry->hdr = hdr;

	if (entry->hdr)
		entry->hdr->ref_cnt++;

	return 0;

error:
	return -EPERM;
}

/**
 * ipa_mdfy_rt_rule() - Modify the specified routing rules in SW and optionally
 * commit to IPA HW
 *
 * Returns:	0 on success, negative on failure
 *
 * Note:	Should not be called from atomic context
 */
int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *hdls)
{
	int i;
	int result;

	if (hdls == NULL || hdls->num_rules == 0 || hdls->ip >= IPA_IP_MAX) {
		IPAERR("bad parm\n");
		return -EINVAL;
	}

	mutex_lock(&ipa_ctx->lock);
	for (i = 0; i < hdls->num_rules; i++) {
		if (__ipa_mdfy_rt_rule(&hdls->rules[i])) {
			IPAERR("failed to mdfy rt rule %i\n", i);
			hdls->rules[i].status = IPA_RT_STATUS_OF_MDFY_FAILED;
		} else {
			hdls->rules[i].status = 0;
		}
	}

	if (hdls->commit)
		if (ipa_ctx->ctrl->ipa_commit_rt(hdls->ip)) {
			result = -EPERM;
			goto bail;
		}
	result = 0;
bail:
	mutex_unlock(&ipa_ctx->lock);

	return result;
}
EXPORT_SYMBOL(ipa_mdfy_rt_rule);
+7 −0
Original line number Diff line number Diff line
@@ -1010,6 +1010,8 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl);

int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in);

int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules);

/*
 * Filtering
 */
@@ -1381,6 +1383,11 @@ static inline int ipa_query_rt_index(struct ipa_ioc_get_rt_tbl_indx *in)
	return -EPERM;
}

static inline int ipa_mdfy_rt_rule(struct ipa_ioc_mdfy_rt_rule *rules)
{
	return -EPERM;
}

/*
 * Filtering
 */
+43 −1
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@
#define IPA_IOCTL_NOTIFY_WAN_EMBMS_CONNECTED	39
#define IPA_IOCTL_ADD_HDR_PROC_CTX 40
#define IPA_IOCTL_DEL_HDR_PROC_CTX 41
#define IPA_IOCTL_MAX 42
#define IPA_IOCTL_MDFY_RT_RULE 42
#define IPA_IOCTL_MAX 43

/**
 * max size of the header to be inserted
@@ -250,6 +251,9 @@ enum ipa_flt_action {
 * wlan ap disconnect: wlan AP(access point) is down
 * wlan sta connect: wlan STA(station) is up
 * wlan sta disconnect: wlan STA(station) is down
 * wlan client connect ex: new wlan client connected
 * wlan scc switch: wlan interfaces in scc mode
 * wlan mcc switch: wlan interfaces in mcc mode
 */
enum ipa_wlan_event {
	WLAN_CLIENT_CONNECT,
@@ -263,6 +267,8 @@ enum ipa_wlan_event {
	WLAN_STA_CONNECT,
	WLAN_STA_DISCONNECT,
	WLAN_CLIENT_CONNECT_EX,
	WLAN_SWITCH_TO_SCC,
	WLAN_SWITCH_TO_MCC,
	IPA_WLAN_EVENT_MAX
};

@@ -782,6 +788,37 @@ struct ipa_ioc_add_rt_rule {
	struct ipa_rt_rule_add rules[0];
};

/**
 * struct ipa_rt_rule_mdfy - routing rule descriptor includes
 * in and out parameters
 * @rule: actual rule to be added
 * @rt_rule_hdl: handle to rule which supposed to modify
 * @status:	output parameter, status of routing rule modify  operation,
 *		0 for success,
 *		-1 for failure
 *
 */
struct ipa_rt_rule_mdfy {
	struct ipa_rt_rule rule;
	uint32_t rt_rule_hdl;
	int status;
};

/**
 * struct ipa_ioc_mdfy_rt_rule - routing rule modify parameters (supports
 * multiple rules and commit)
 * @commit: should rules be written to IPA HW also?
 * @ip: IP family of rule
 * @num_rules: number of routing rules that follow
 * @rules: all rules need to go back to back here, no pointers
 */
struct ipa_ioc_mdfy_rt_rule {
	uint8_t commit;
	enum ipa_ip_type ip;
	uint8_t num_rules;
	struct ipa_rt_rule_mdfy rules[0];
};

/**
 * struct ipa_rt_rule_del - routing rule descriptor includes in
 * and out parameters
@@ -963,6 +1000,7 @@ struct ipa_ioc_query_intf {
 * @ip: IP family of routing rule
 * @attrib: routing rule
 * @dst_pipe: routing output pipe
 * @alt_dst_pipe: alternate routing output pipe
 * @hdr_name: name of associated header if any, empty string when no header
 * @hdr_l2_type: type of associated header if any, use NONE when no header
 */
@@ -970,6 +1008,7 @@ struct ipa_ioc_tx_intf_prop {
	enum ipa_ip_type ip;
	struct ipa_rule_attrib attrib;
	enum ipa_client_type dst_pipe;
	enum ipa_client_type alt_dst_pipe;
	char hdr_name[IPA_RESOURCE_NAME_MAX];
	enum ipa_hdr_l2_type hdr_l2_type;
};
@@ -1354,6 +1393,9 @@ struct ipa_ioc_write_qmapid {
#define IPA_IOC_MDFY_FLT_RULE _IOWR(IPA_IOC_MAGIC, \
					IPA_IOCTL_MDFY_FLT_RULE, \
					struct ipa_ioc_mdfy_flt_rule *)
#define IPA_IOC_MDFY_RT_RULE _IOWR(IPA_IOC_MAGIC, \
					IPA_IOCTL_MDFY_RT_RULE, \
					struct ipa_ioc_mdfy_rt_rule *)

#define IPA_IOC_NOTIFY_WAN_UPSTREAM_ROUTE_ADD _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_NOTIFY_WAN_UPSTREAM_ROUTE_ADD, \