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

Commit 58d66530 authored by Jinesh K. Jayakumar's avatar Jinesh K. Jayakumar Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: eth: Register interface properties when offload is started



IPA downlink filter rules can get installed during an ethernet link up
event even though the offload path is stopped if we keep the interface
properties registered, leading to data stalls. Register interface with
IPA driver and send offload event to userspace when offload is started.

Change-Id: I202ff0ea863d62be89fdc7b30b480044c7b61931
Signed-off-by: default avatarJinesh K. Jayakumar <jineshk@codeaurora.org>
parent 5027af9b
Loading
Loading
Loading
Loading
+13 −41
Original line number Diff line number Diff line
@@ -14,8 +14,6 @@
#include <linux/suspend.h>
#include <linux/timer.h>

#include <linux/msm_ipa.h>

#include "ipa_eth_i.h"

unsigned long ipa_eth_state;
@@ -105,13 +103,6 @@ static int ipa_eth_init_device(struct ipa_eth_device *eth_dev)
		return rc;
	}

	rc = ipa_eth_ep_register_interface(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to register EP interface");
		eth_dev->of_state = IPA_ETH_OF_ST_ERROR;
		return rc;
	}

	ipa_eth_dev_log(eth_dev, "Initialized device");

	eth_dev->of_state = IPA_ETH_OF_ST_INITED;
@@ -129,13 +120,6 @@ static int ipa_eth_deinit_device(struct ipa_eth_device *eth_dev)
	if (eth_dev->of_state != IPA_ETH_OF_ST_INITED)
		return -EFAULT;

	rc = ipa_eth_ep_unregister_interface(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to unregister IPA interface");
		eth_dev->of_state = IPA_ETH_OF_ST_ERROR;
		return rc;
	}

	rc = ipa_eth_offload_deinit(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to deinit offload");
@@ -164,13 +148,9 @@ static int ipa_eth_deinit_device(struct ipa_eth_device *eth_dev)
	return 0;
}

static void ipa_eth_free_msg(void *buff, u32 len, u32 type) {}

static int ipa_eth_start_device(struct ipa_eth_device *eth_dev)
{
	int rc;
	struct ipa_msg_meta msg_meta;
	struct ipa_ecm_msg ecm_msg;

	if (eth_dev->of_state == IPA_ETH_OF_ST_STARTED)
		return 0;
@@ -200,15 +180,12 @@ static int ipa_eth_start_device(struct ipa_eth_device *eth_dev)
		return rc;
	}

	memset(&msg_meta, 0, sizeof(msg_meta));
	memset(&ecm_msg, 0, sizeof(ecm_msg));

	ecm_msg.ifindex = eth_dev->net_dev->ifindex;
	strlcpy(ecm_msg.name, eth_dev->net_dev->name, IPA_RESOURCE_NAME_MAX);

	msg_meta.msg_type = ECM_CONNECT;
	msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
	(void) ipa_send_msg(&msg_meta, &ecm_msg, ipa_eth_free_msg);
	rc = ipa_eth_ep_register_interface(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to register EP interface");
		eth_dev->of_state = IPA_ETH_OF_ST_ERROR;
		return rc;
	}

	ipa_eth_dev_log(eth_dev, "Started device");

@@ -220,18 +197,6 @@ static int ipa_eth_start_device(struct ipa_eth_device *eth_dev)
static int ipa_eth_stop_device(struct ipa_eth_device *eth_dev)
{
	int rc;
	struct ipa_msg_meta msg_meta;
	struct ipa_ecm_msg ecm_msg;

	memset(&msg_meta, 0, sizeof(msg_meta));
	memset(&ecm_msg, 0, sizeof(ecm_msg));

	ecm_msg.ifindex = eth_dev->net_dev->ifindex;
	strlcpy(ecm_msg.name, eth_dev->net_dev->name, IPA_RESOURCE_NAME_MAX);

	msg_meta.msg_type = ECM_DISCONNECT;
	msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
	(void) ipa_send_msg(&msg_meta, &ecm_msg, ipa_eth_free_msg);

	if (eth_dev->of_state == IPA_ETH_OF_ST_DEINITED)
		return 0;
@@ -239,6 +204,13 @@ static int ipa_eth_stop_device(struct ipa_eth_device *eth_dev)
	if (eth_dev->of_state != IPA_ETH_OF_ST_STARTED)
		return -EFAULT;

	rc = ipa_eth_ep_unregister_interface(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to unregister IPA interface");
		eth_dev->of_state = IPA_ETH_OF_ST_ERROR;
		return rc;
	}

	rc = ipa_eth_bus_enable_pc(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev,
+9 −1
Original line number Diff line number Diff line
@@ -323,6 +323,8 @@ int ipa_eth_ep_register_interface(struct ipa_eth_device *eth_dev)
		goto free_and_exit;

	rc = ipa_register_intf(eth_dev->net_dev->name, &tx_intf, &rx_intf);
	if (!rc)
		ipa_eth_send_msg_connect(eth_dev);

free_and_exit:
	kzfree(tx_intf.prop);
@@ -338,7 +340,13 @@ int ipa_eth_ep_register_interface(struct ipa_eth_device *eth_dev)
 */
int ipa_eth_ep_unregister_interface(struct ipa_eth_device *eth_dev)
{
	return ipa_deregister_intf(eth_dev->net_dev->name);
	int rc;

	rc = ipa_deregister_intf(eth_dev->net_dev->name);
	if (!rc)
		ipa_eth_send_msg_disconnect(eth_dev);

	return rc;
}

/**
+2 −0
Original line number Diff line number Diff line
@@ -197,6 +197,8 @@ int ipa_eth_pm_vote_bw(struct ipa_eth_device *eth_dev);
/* ipa_eth_utils.c APIs */

const char *ipa_eth_device_event_name(enum ipa_eth_device_event event);
int ipa_eth_send_msg_connect(struct ipa_eth_device *eth_dev);
int ipa_eth_send_msg_disconnect(struct ipa_eth_device *eth_dev);

void *ipa_eth_get_ipc_logbuf(void);
void *ipa_eth_get_ipc_logbuf_dbg(void);
+33 −0
Original line number Diff line number Diff line
@@ -29,6 +29,39 @@ const char *ipa_eth_device_event_name(enum ipa_eth_device_event event)
	return name;
}

static void __ipa_eth_free_msg(void *buff, u32 len, u32 type) {}

static int ipa_eth_send_ecm_msg(struct ipa_eth_device *eth_dev,
		enum ipa_ecm_event ecm_event)
{
	struct ipa_msg_meta msg_meta;
	struct ipa_ecm_msg ecm_msg;

	if (!eth_dev || !eth_dev->net_dev)
		return -EFAULT;

	memset(&msg_meta, 0, sizeof(msg_meta));
	memset(&ecm_msg, 0, sizeof(ecm_msg));

	ecm_msg.ifindex = eth_dev->net_dev->ifindex;
	strlcpy(ecm_msg.name, eth_dev->net_dev->name, IPA_RESOURCE_NAME_MAX);

	msg_meta.msg_type = ecm_event;
	msg_meta.msg_len = sizeof(struct ipa_ecm_msg);

	return ipa_send_msg(&msg_meta, &ecm_msg, __ipa_eth_free_msg);
}

int ipa_eth_send_msg_connect(struct ipa_eth_device *eth_dev)
{
	return ipa_eth_send_ecm_msg(eth_dev, ECM_CONNECT);
}

int ipa_eth_send_msg_disconnect(struct ipa_eth_device *eth_dev)
{
	return ipa_eth_send_ecm_msg(eth_dev, ECM_DISCONNECT);
}

/* IPC Logging */

bool ipa_eth_ipc_logdbg = IPA_ETH_IPC_LOGDBG_DEFAULT;