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

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

Merge "msm: ipa: Add support in offload sub-system to handle netdevice SSR"

parents f526f522 0a054dfc
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@ ipa-eth-y := \
	ipa_eth_offload.o \
	ipa_eth_pci.o \
	ipa_eth_pm.o \
	ipa_eth_uc.o
	ipa_eth_uc.o \
	ipa_eth_utils.o

ifneq ($(wildcard $(srctree)/$(src)/aquantia/Makefile),)
obj-$(CONFIG_AQC_IPA) += aquantia/
+56 −4
Original line number Diff line number Diff line
@@ -260,11 +260,8 @@ static int ipa_eth_stop_device(struct ipa_eth_device *eth_dev)
	return 0;
}

static void __ipa_eth_refresh_device(struct work_struct *work)
static void __ipa_eth_refresh(struct ipa_eth_device *eth_dev)
{
	struct ipa_eth_device *eth_dev = container_of(work,
				struct ipa_eth_device, refresh);

	ipa_eth_dev_log(eth_dev, "Refreshing offload state for device");

	if (!ipa_eth_offload_device_paired(eth_dev)) {
@@ -335,6 +332,16 @@ static void __ipa_eth_refresh_device(struct work_struct *work)
	}
}

static void __ipa_eth_refresh_device(struct work_struct *work)
{
	struct ipa_eth_device *eth_dev = container_of(work,
				struct ipa_eth_device, refresh);

	mutex_lock(&eth_dev->refresh_mutex);
	__ipa_eth_refresh(eth_dev);
	mutex_unlock(&eth_dev->refresh_mutex);
}

static void ipa_eth_refresh_device(struct ipa_eth_device *eth_dev)
{
	if (ipa_eth_ready())
@@ -365,6 +372,50 @@ static void ipa_eth_refresh_devices(void)
	queue_work(ipa_eth_wq, &global_refresh);
}

/**
 * ipa_eth_device_notify() - Notifies a device event to the offload sub-system
 * @eth_dev: Device for which the event is generated
 * @event: Device event
 * @data: Event specific data, if required
 *
 * Return: 0 on success, non-zero otherwise
 */
int ipa_eth_device_notify(struct ipa_eth_device *eth_dev,
	enum ipa_eth_device_event event, void *data)
{
	int rc = -EINVAL;

	ipa_eth_dev_log(eth_dev,
		"Received notificaiton %s", ipa_eth_device_event_name(event));

	mutex_lock(&eth_dev->refresh_mutex);

	switch (event) {
	case IPA_ETH_DEV_RESET_PREPARE:
		IPA_ACTIVE_CLIENTS_INC_SIMPLE();
		rc = ipa_eth_offload_prepare_reset(eth_dev, data);
		IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
		break;
	case IPA_ETH_DEV_RESET_COMPLETE:
		IPA_ACTIVE_CLIENTS_INC_SIMPLE();
		rc = ipa_eth_offload_complete_reset(eth_dev, data);
		IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
		break;
	default:
		break;
	}

	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to handle notification");
		eth_dev->of_state = IPA_ETH_OF_ST_ERROR;
	}

	mutex_unlock(&eth_dev->refresh_mutex);

	return rc;
}
EXPORT_SYMBOL(ipa_eth_device_notify);

static void ipa_eth_dev_start_timer_cb(unsigned long data)
{
	struct ipa_eth_device *eth_dev = (struct ipa_eth_device *)data;
@@ -701,6 +752,7 @@ int ipa_eth_register_device(struct ipa_eth_device *eth_dev)
	eth_dev->of_state = IPA_ETH_OF_ST_DEINITED;
	eth_dev->pm_handle = IPA_PM_MAX_CLIENTS;
	INIT_WORK(&eth_dev->refresh, __ipa_eth_refresh_device);
	mutex_init(&eth_dev->refresh_mutex);

	INIT_LIST_HEAD(&eth_dev->rx_channels);
	INIT_LIST_HEAD(&eth_dev->tx_channels);
+4 −0
Original line number Diff line number Diff line
@@ -147,6 +147,8 @@ int ipa_eth_offload_start(struct ipa_eth_device *eth_dev);
int ipa_eth_offload_stop(struct ipa_eth_device *eth_dev);

int ipa_eth_offload_save_regs(struct ipa_eth_device *eth_dev);
int ipa_eth_offload_prepare_reset(struct ipa_eth_device *eth_dev, void *data);
int ipa_eth_offload_complete_reset(struct ipa_eth_device *eth_dev, void *data);

int ipa_eth_net_open_device(struct ipa_eth_device *eth_dev);
void ipa_eth_net_close_device(struct ipa_eth_device *eth_dev);
@@ -167,4 +169,6 @@ int ipa_eth_pm_deactivate(struct ipa_eth_device *eth_dev);

int ipa_eth_pm_vote_bw(struct ipa_eth_device *eth_dev);

const char *ipa_eth_device_event_name(enum ipa_eth_device_event event);

#endif // _IPA_ETH_I_H_
+20 −0
Original line number Diff line number Diff line
@@ -224,6 +224,26 @@ int ipa_eth_offload_save_regs(struct ipa_eth_device *eth_dev)
	return 0;
}

int ipa_eth_offload_prepare_reset(struct ipa_eth_device *eth_dev, void *data)
{
	struct ipa_eth_offload_driver *od = eth_dev->od;

	if (od && od->ops->prepare_reset)
		return eth_dev->od->ops->prepare_reset(eth_dev, data);

	return 0;
}

int ipa_eth_offload_complete_reset(struct ipa_eth_device *eth_dev, void *data)
{
	struct ipa_eth_offload_driver *od = eth_dev->od;

	if (od && od->ops->complete_reset)
		return eth_dev->od->ops->complete_reset(eth_dev, data);

	return 0;
}

int ipa_eth_offload_modinit(struct dentry *dbgfs_root)
{
	int rc;
+28 −0
Original line number Diff line number Diff line
/* Copyright (c) 2019 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "ipa_eth_i.h"

static const char * const ipa_eth_device_events[IPA_ETH_DEV_EVENT_COUNT] = {
	[IPA_ETH_DEV_RESET_PREPARE] = "RESET_PREPARE",
	[IPA_ETH_DEV_RESET_COMPLETE] = "RESET_COMPLETE",
};

const char *ipa_eth_device_event_name(enum ipa_eth_device_event event)
{
	const char *name = "<unknown>";

	if (event < IPA_ETH_DEV_EVENT_COUNT && ipa_eth_device_events[event])
		name = ipa_eth_device_events[event];

	return name;
}
Loading