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

Commit 4c009919 authored by Ravi Gummadidala's avatar Ravi Gummadidala Committed by Skylar Chang
Browse files

msm: ipa: provide ECM connect and disconnect using IPA messaging



This supplements the exiting mechanism based on netlink events.
This is added because in some cases, the netlink events are
not seen at user-space leading to device crash.

Change-Id: I3f13b45a80bb0792b8c6cc36de909f842f4beb83
Signed-off-by: default avatarRavi Gummadidala <rgummadi@codeaurora.org>
parent 4db175e5
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -194,6 +194,11 @@ const struct file_operations ecm_ipa_debugfs_atomic_ops = {
	.read = ecm_ipa_debugfs_atomic_read,
};

static void ecm_ipa_msg_free_cb(void *buff, u32 len, u32 type)
{
	kfree(buff);
}

/**
 * ecm_ipa_init() - create network device and initializes internal
 *  data structures
@@ -345,12 +350,21 @@ int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl,
{
	struct ecm_ipa_dev *ecm_ipa_ctx = priv;
	int next_state;
	struct ipa_ecm_msg *ecm_msg;
	struct ipa_msg_meta msg_meta;
	int retval;

	ECM_IPA_LOG_ENTRY();
	NULL_CHECK(priv);
	ECM_IPA_DEBUG("usb_to_ipa_hdl = %d, ipa_to_usb_hdl = %d, priv=0x%p\n",
					usb_to_ipa_hdl, ipa_to_usb_hdl, priv);

	ecm_msg = kzalloc(sizeof(struct ipa_ecm_msg), GFP_KERNEL);
	if (!ecm_msg) {
		ECM_IPA_ERROR("can't alloc msg mem\n");
		return -ENOMEM;
	}

	next_state = ecm_ipa_next_state(ecm_ipa_ctx->state, ECM_IPA_CONNECT);
	if (next_state == ECM_IPA_INVALID) {
		ECM_IPA_ERROR("can't call connect before calling initialize\n");
@@ -375,6 +389,21 @@ int ecm_ipa_connect(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl,
	ECM_IPA_DEBUG("end-point configured\n");

	netif_carrier_on(ecm_ipa_ctx->net);

	memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
	msg_meta.msg_type = ECM_CONNECT;
	msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
	strlcpy(ecm_msg->name, ecm_ipa_ctx->net->name,
		IPA_RESOURCE_NAME_MAX);
	ecm_msg->ifindex = ecm_ipa_ctx->net->ifindex;

	retval = ipa_send_msg(&msg_meta, ecm_msg, ecm_ipa_msg_free_cb);
	if (retval) {
		ECM_IPA_ERROR("fail to send ECM_CONNECT message\n");
		kfree(ecm_msg);
		return -EPERM;
	}

	if (!netif_carrier_ok(ecm_ipa_ctx->net)) {
		ECM_IPA_ERROR("netif_carrier_ok error\n");
		return -EBUSY;
@@ -602,11 +631,20 @@ int ecm_ipa_disconnect(void *priv)
{
	struct ecm_ipa_dev *ecm_ipa_ctx = priv;
	int next_state;
	struct ipa_ecm_msg *ecm_msg;
	struct ipa_msg_meta msg_meta;
	int retval;

	ECM_IPA_LOG_ENTRY();
	NULL_CHECK(ecm_ipa_ctx);
	ECM_IPA_DEBUG("priv=0x%p\n", priv);

	ecm_msg = kzalloc(sizeof(struct ipa_ecm_msg), GFP_KERNEL);
	if (!ecm_msg) {
		ECM_IPA_ERROR("can't alloc msg mem\n");
		return -ENOMEM;
	}

	next_state = ecm_ipa_next_state(ecm_ipa_ctx->state, ECM_IPA_DISCONNECT);
	if (next_state == ECM_IPA_INVALID) {
		ECM_IPA_ERROR("can't disconnect before connect\n");
@@ -618,6 +656,20 @@ int ecm_ipa_disconnect(void *priv)
	netif_carrier_off(ecm_ipa_ctx->net);
	ECM_IPA_DEBUG("carrier_off notifcation was sent\n");

	memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
	msg_meta.msg_type = ECM_DISCONNECT;
	msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
	strlcpy(ecm_msg->name, ecm_ipa_ctx->net->name,
		IPA_RESOURCE_NAME_MAX);
	ecm_msg->ifindex = ecm_ipa_ctx->net->ifindex;

	retval = ipa_send_msg(&msg_meta, ecm_msg, ecm_ipa_msg_free_cb);
	if (retval) {
		ECM_IPA_ERROR("fail to send ECM_DISCONNECT message\n");
		kfree(ecm_msg);
		return -EPERM;
	}

	netif_stop_queue(ecm_ipa_ctx->net);
	ECM_IPA_DEBUG("queue stopped\n");

+3 −1
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(ECM_CONNECT),
	__stringify(ECM_DISCONNECT),
};

static struct dentry *dent;
@@ -927,7 +929,7 @@ static ssize_t ipa_read_msg(struct file *file, char __user *ubuf,
	int cnt = 0;
	int i;

	for (i = 0; i < IPA_EVENT_MAX; i++) {
	for (i = 0; i < IPA_EVENT_MAX_NUM; i++) {
		nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt,
				"msg[%u:%27s] W:%u R:%u\n", i,
				ipa_event_name[i],
+2 −2
Original line number Diff line number Diff line
@@ -559,8 +559,8 @@ struct ipa_stats {
	u32 rx_repl_repost;
	u32 tx_pkts_compl;
	u32 rx_q_len;
	u32 msg_w[IPA_EVENT_MAX];
	u32 msg_r[IPA_EVENT_MAX];
	u32 msg_w[IPA_EVENT_MAX_NUM];
	u32 msg_r[IPA_EVENT_MAX_NUM];
	u32 a2_power_on_reqs_in;
	u32 a2_power_on_reqs_out;
	u32 a2_power_off_reqs_in;
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -368,7 +368,7 @@ int ipa_send_msg(struct ipa_msg_meta *meta, void *buff,
		return -EINVAL;
	}

	if (meta->msg_type >= IPA_EVENT_MAX) {
	if (meta->msg_type >= IPA_EVENT_MAX_NUM) {
		IPAERR("unsupported message type %d\n", meta->msg_type);
		return -EINVAL;
	}
+12 −1
Original line number Diff line number Diff line
@@ -216,7 +216,13 @@ enum ipa_wlan_event {
	IPA_WLAN_EVENT_MAX
};

#define IPA_EVENT_MAX ((int)IPA_WLAN_EVENT_MAX)
enum ipa_ecm_event {
	ECM_CONNECT = IPA_WLAN_EVENT_MAX,
	ECM_DISCONNECT,
	IPA_EVENT_MAX_NUM
};

#define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM)

/**
 * enum ipa_rm_resource_name - IPA RM clients identification names
@@ -974,6 +980,11 @@ struct ipa_wlan_msg_ex {
	struct ipa_wlan_hdr_attrib_val attribs[0];
};

struct ipa_ecm_msg {
	char name[IPA_RESOURCE_NAME_MAX];
	int ifindex;
};

/**
 * struct ipa_ioc_rm_dependency - parameters for add/delete dependency
 * @resource_name: name of dependent resource