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

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

Merge "msm: ipa: Enable support for dynamic loading of clients"

parents b4a41c45 ae65b03f
Loading
Loading
Loading
Loading
+43 −14
Original line number Diff line number Diff line
@@ -27,6 +27,11 @@ enum ipa_eth_states {
	IPA_ETH_ST_MAX,
};

enum ipa_eth_dev_states {
	IPA_ETH_DEV_ST_UNPAIRING,
	IPA_ETH_DEV_ST_MAX,
};

static unsigned long ipa_eth_state;

static struct dentry *ipa_eth_debugfs;
@@ -56,12 +61,15 @@ static inline bool ipa_eth_ready(void)

static inline bool initable(struct ipa_eth_device *eth_dev)
{
	return eth_dev->init;
	return !test_bit(IPA_ETH_DEV_ST_UNPAIRING, &eth_dev->state) &&
		eth_dev->init;
}

static inline bool startable(struct ipa_eth_device *eth_dev)
{
	return eth_dev->init && eth_dev->start &&
	return !test_bit(IPA_ETH_DEV_ST_UNPAIRING, &eth_dev->state) &&
		eth_dev->init &&
		eth_dev->start &&
		test_bit(IPA_ETH_IF_ST_LOWER_UP, &eth_dev->if_state);
}

@@ -148,9 +156,13 @@ 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;
@@ -180,6 +192,16 @@ 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);

	ipa_eth_dev_log(eth_dev, "Started device");

	eth_dev->of_state = IPA_ETH_OF_ST_STARTED;
@@ -190,6 +212,18 @@ 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;
@@ -342,7 +376,7 @@ static void ipa_eth_dev_start_timer_cb(unsigned long data)
	ipa_eth_refresh_device(eth_dev);
}

static int ipa_eth_netdev_event_change(struct ipa_eth_device *eth_dev)
static int __ipa_eth_netdev_event(struct ipa_eth_device *eth_dev)
{
	bool refresh_needed = netif_carrier_ok(eth_dev->net_dev) ?
		!test_and_set_bit(IPA_ETH_IF_ST_LOWER_UP, &eth_dev->if_state) :
@@ -365,17 +399,9 @@ static int ipa_eth_netdev_event(struct notifier_block *nb,
	if (net_dev != eth_dev->net_dev)
		return NOTIFY_DONE;

	ipa_eth_dev_log(eth_dev, "Received netdev event %lu", event);
	ipa_eth_dev_log(eth_dev, "Received netdev event 0x%04lx", event);

	switch (event) {
	case NETDEV_CHANGE:
		return ipa_eth_netdev_event_change(eth_dev);
	default:
		/* Ignore other events */
		break;
	}

	return NOTIFY_DONE;
	return __ipa_eth_netdev_event(eth_dev);
}

static int ipa_eth_uc_ready_cb(struct notifier_block *nb,
@@ -620,7 +646,7 @@ static void __ipa_eth_unpair_device(struct ipa_eth_device *eth_dev)

	flush_work(&eth_dev->refresh);

	eth_dev->init = eth_dev->start = false;
	set_bit(IPA_ETH_DEV_ST_UNPAIRING, &eth_dev->state);

	ipa_eth_refresh_device(eth_dev);
	flush_work(&eth_dev->refresh);
@@ -628,6 +654,8 @@ static void __ipa_eth_unpair_device(struct ipa_eth_device *eth_dev)

	unregister_netdevice_notifier(&eth_dev->netdevice_nb);
	ipa_eth_offload_unpair_device(eth_dev);

	clear_bit(IPA_ETH_DEV_ST_UNPAIRING, &eth_dev->state);
}

static void ipa_eth_pair_devices(void)
@@ -904,6 +932,7 @@ int ipa_eth_register_offload_driver(struct ipa_eth_offload_driver *od)
	ipa_eth_log("Registered offload driver %s", od->name);

	ipa_eth_pair_devices();
	ipa_eth_refresh_devices();

	return 0;
}
+8 −0
Original line number Diff line number Diff line
@@ -242,6 +242,14 @@ int ipa_eth_gsi_dealloc(struct ipa_eth_channel *ch)
	}

	if (ep_ctx->gsi_evt_ring_hdl != ~0) {
		gsi_rc = gsi_reset_evt_ring(ep_ctx->gsi_evt_ring_hdl);
		if (gsi_rc != GSI_STATUS_SUCCESS) {
			ipa_eth_dev_err(ch->eth_dev,
				"Failed to reset event ring %lu",
				ep_ctx->gsi_evt_ring_hdl);
			return gsi_rc;
		}

		gsi_rc = gsi_dealloc_evt_ring(ep_ctx->gsi_evt_ring_hdl);
		if (gsi_rc != GSI_STATUS_SUCCESS) {
			ipa_eth_dev_err(ch->eth_dev,
+2 −0
Original line number Diff line number Diff line
@@ -207,6 +207,8 @@ int ipa_eth_offload_register_driver(struct ipa_eth_offload_driver *od)

void ipa_eth_offload_unregister_driver(struct ipa_eth_offload_driver *od)
{
	debugfs_remove_recursive(od->debugfs);

	mutex_lock(&ipa_eth_offload_drivers_lock);
	list_del(&od->driver_list);
	mutex_unlock(&ipa_eth_offload_drivers_lock);
+4 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 */

#include <linux/ethtool.h>
#include <linux/rtnetlink.h>

#include "ipa_eth_i.h"

@@ -100,7 +101,10 @@ static u32 __fetch_ethtool_link_speed(struct ipa_eth_device *eth_dev)
	int rc;
	struct ethtool_link_ksettings link_ksettings;

	rtnl_lock();
	rc = __ethtool_get_link_ksettings(eth_dev->net_dev, &link_ksettings);
	rtnl_unlock();

	if (rc) {
		ipa_eth_dev_err(eth_dev,
			"Failed to obtain link settings via ethtool");
+2 −0
Original line number Diff line number Diff line
@@ -440,6 +440,7 @@ struct ipa_eth_channel {
 * @start_on_resume: Allow start upon driver resume
 * @start_on_timeout: Timeout in milliseconds after which @start is enabled
 * @start_timer: Timer associated with @start_on_timer
 * @state: Device state
 * @if_state: Interface state - one or more bit numbers IPA_ETH_IF_ST_*
 * @pm_handle: IPA PM client handle for the device
 * @bus_priv: Private field for use by offload subsystem bus layer
@@ -478,6 +479,7 @@ struct ipa_eth_device {
	u32 start_on_timeout;
	struct timer_list start_timer;

	unsigned long state;
	unsigned long if_state;

	u32 pm_handle;