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

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

Merge "msm: ipa: eth: Explicitly fetch initial link status"

parents ed216b2c 95c291e8
Loading
Loading
Loading
Loading
+58 −39
Original line number Diff line number Diff line
@@ -430,6 +430,28 @@ static int ipa_eth_device_complete_reset(
	return rc;
}

static int ipa_eth_device_event_add_macsec(
	struct ipa_eth_device *eth_dev, void *data)
{
	struct net_device *net_dev = data;

	ipa_eth_dev_log(eth_dev,
		"Network device added MACSec interface %s", net_dev->name);

	return 0;
}

static int ipa_eth_device_event_del_macsec(
	struct ipa_eth_device *eth_dev, void *data)
{
	struct net_device *net_dev = data;

	ipa_eth_dev_log(eth_dev,
		"Network device removed MACSec interface %s", net_dev->name);

	return 0;
}

/**
 * ipa_eth_device_notify() - Notifies a device event to the offload sub-system
 * @eth_dev: Device for which the event is generated
@@ -453,8 +475,14 @@ int ipa_eth_device_notify(struct ipa_eth_device *eth_dev,
	case IPA_ETH_DEV_RESET_COMPLETE:
		rc = ipa_eth_device_complete_reset(eth_dev, data);
		break;
	case IPA_ETH_DEV_ADD_MACSEC_IF:
		rc = ipa_eth_device_event_add_macsec(eth_dev, data);
		break;
	case IPA_ETH_DEV_DEL_MACSEC_IF:
		rc = ipa_eth_device_event_del_macsec(eth_dev, data);
		break;
	default:
		ipa_eth_dev_log(eth_dev, "Skipped event processing");
		ipa_eth_dev_log(eth_dev, "Unknown event %d", event);
		break;
	}

@@ -502,6 +530,22 @@ static void ipa_eth_ipa_ready_cb(void *data)
	ipa_eth_global_refresh_sched();
}

static int ipa_eth_panic_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
	struct ipa_eth_device_private *ipa_priv = container_of(nb,
				struct ipa_eth_device_private, panic_nb);
	struct ipa_eth_device *eth_dev = ipa_priv->eth_dev;

	if (!reachable(eth_dev))
		return -ENODEV;

	ipa_eth_net_save_regs(eth_dev);
	ipa_eth_offload_save_regs(eth_dev);

	return NOTIFY_DONE;
}

/*
 * ipa_eth_alloc_device() - Allocate an ipa_eth_device structure and initialize
 *                          all common fields
@@ -555,9 +599,13 @@ struct ipa_eth_device *ipa_eth_alloc_device(

	/* Initialize private data */

	ipa_priv->eth_dev = eth_dev;

	mutex_init(&ipa_priv->upper_mutex);
	INIT_LIST_HEAD(&ipa_priv->upper_devices);

	ipa_priv->panic_nb.notifier_call = ipa_eth_panic_notifier;

	eth_dev->ipa_priv = ipa_priv;

	return eth_dev;
@@ -587,9 +635,13 @@ void ipa_eth_free_device(struct ipa_eth_device *eth_dev)
int ipa_eth_register_device(struct ipa_eth_device *eth_dev)
{
	int rc;
	struct ipa_eth_device_private *ipa_priv = eth_dev->ipa_priv;

	ipa_eth_dev_log(eth_dev, "Registering new device");

	(void) atomic_notifier_chain_register(
			&panic_notifier_list, &ipa_priv->panic_nb);

	rc = ipa_eth_net_open_device(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to open network device");
@@ -651,6 +703,8 @@ static void ipa_eth_unpair_device(struct ipa_eth_device *eth_dev)
 */
void ipa_eth_unregister_device(struct ipa_eth_device *eth_dev)
{
	struct ipa_eth_device_private *ipa_priv = eth_dev->ipa_priv;

	ipa_eth_dev_log(eth_dev, "Unregistering device");

	/* Set REMOVING flag so that device refreshes do not happen */
@@ -691,6 +745,9 @@ void ipa_eth_unregister_device(struct ipa_eth_device *eth_dev)
	 */
	clear_bit(IPA_ETH_DEV_F_REMOVING, &eth_dev->flags);

	(void) atomic_notifier_chain_unregister(
			&panic_notifier_list, &ipa_priv->panic_nb);

	ipa_eth_dev_log(eth_dev, "Device unregistered");
}

@@ -773,36 +830,6 @@ void ipa_eth_unregister_offload_driver(struct ipa_eth_offload_driver *od)
}
EXPORT_SYMBOL(ipa_eth_unregister_offload_driver);

static int ipa_eth_panic_save_device(struct ipa_eth_device *eth_dev)
{
	if (!reachable(eth_dev))
		return -ENODEV;

	ipa_eth_net_save_regs(eth_dev);
	ipa_eth_offload_save_regs(eth_dev);

	return 0;
}

static int ipa_eth_panic_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
	struct ipa_eth_device *eth_dev;

	mutex_lock(&ipa_eth_devices_lock);

	list_for_each_entry(eth_dev, &ipa_eth_devices, device_list)
		ipa_eth_panic_save_device(eth_dev);

	mutex_unlock(&ipa_eth_devices_lock);

	return NOTIFY_DONE;
}

static struct notifier_block ipa_eth_panic_nb = {
	.notifier_call  = ipa_eth_panic_notifier,
};

static int ipa_eth_pm_notifier_cb(struct notifier_block *nb,
	unsigned long pm_event, void *unused)
{
@@ -830,9 +857,6 @@ int ipa_eth_init(void)
	int rc;
	unsigned int wq_flags = WQ_UNBOUND | WQ_MEM_RECLAIM;

	(void) atomic_notifier_chain_register(
			&panic_notifier_list, &ipa_eth_panic_nb);

	rc = ipa_eth_ipc_log_init();
	if (rc) {
		ipa_eth_err("Failed to initialize IPC logging");
@@ -904,8 +928,6 @@ int ipa_eth_init(void)
err_wq:
	ipa_eth_ipc_log_cleanup();
err_ipclog:
	(void) atomic_notifier_chain_unregister(
			&panic_notifier_list, &ipa_eth_panic_nb);
	return rc;
}

@@ -941,7 +963,4 @@ void ipa_eth_exit(void)
	ipa_eth_wq = NULL;

	ipa_eth_ipc_log_cleanup();

	(void) atomic_notifier_chain_unregister(
			&panic_notifier_list, &ipa_eth_panic_nb);
}
+4 −0
Original line number Diff line number Diff line
@@ -118,8 +118,12 @@ struct ipa_eth_upper_device {
};

struct ipa_eth_device_private {
	struct ipa_eth_device *eth_dev;

	struct mutex upper_mutex;
	struct list_head upper_devices;

	struct notifier_block panic_nb;
};

struct ipa_eth_bus {
+16 −4
Original line number Diff line number Diff line
@@ -355,6 +355,14 @@ static int ipa_eth_net_unlink_upper(struct ipa_eth_device *eth_dev,
	return rc;
}

static bool ipa_eth_net_update_link(struct ipa_eth_device *eth_dev)
{
	return netif_carrier_ok(eth_dev->net_dev) ?
		!test_and_set_bit(IPA_ETH_IF_ST_LOWER_UP, &eth_dev->if_state) :
		test_and_clear_bit(IPA_ETH_IF_ST_LOWER_UP, &eth_dev->if_state);

}

static bool ipa_eth_net_event_up(struct ipa_eth_device *eth_dev,
		unsigned long event, void *ptr)
{
@@ -370,10 +378,7 @@ static bool ipa_eth_net_event_down(struct ipa_eth_device *eth_dev,
static bool ipa_eth_net_event_change(struct ipa_eth_device *eth_dev,
		unsigned long event, void *ptr)
{
	return netif_carrier_ok(eth_dev->net_dev) ?
		!test_and_set_bit(IPA_ETH_IF_ST_LOWER_UP, &eth_dev->if_state) :
		test_and_clear_bit(IPA_ETH_IF_ST_LOWER_UP, &eth_dev->if_state);

	return ipa_eth_net_update_link(eth_dev);
}

static bool ipa_eth_net_event_pre_change_upper(struct ipa_eth_device *eth_dev,
@@ -464,6 +469,13 @@ int ipa_eth_net_open_device(struct ipa_eth_device *eth_dev)
		goto err_register;
	}

	/* When registering with netdevice notifier, only REGISTER and UP events
	 * are replayed. Fetch current link state; future link state updates
	 * will be processed through CHANGE event.
	 */
	if (ipa_eth_net_update_link(eth_dev))
		ipa_eth_device_refresh_sched(eth_dev);

	return 0;

err_register: