Loading drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -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/ Loading drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c +56 −4 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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(ð_dev->refresh_mutex); __ipa_eth_refresh(eth_dev); mutex_unlock(ð_dev->refresh_mutex); } static void ipa_eth_refresh_device(struct ipa_eth_device *eth_dev) { if (ipa_eth_ready()) Loading Loading @@ -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(ð_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(ð_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; Loading Loading @@ -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(ð_dev->refresh, __ipa_eth_refresh_device); mutex_init(ð_dev->refresh_mutex); INIT_LIST_HEAD(ð_dev->rx_channels); INIT_LIST_HEAD(ð_dev->tx_channels); Loading drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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_ drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_utils.c 0 → 100644 +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
drivers/platform/msm/ipa/ipa_v3/ethernet/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -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/ Loading
drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth.c +56 −4 Original line number Diff line number Diff line Loading @@ -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)) { Loading Loading @@ -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(ð_dev->refresh_mutex); __ipa_eth_refresh(eth_dev); mutex_unlock(ð_dev->refresh_mutex); } static void ipa_eth_refresh_device(struct ipa_eth_device *eth_dev) { if (ipa_eth_ready()) Loading Loading @@ -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(ð_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(ð_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; Loading Loading @@ -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(ð_dev->refresh, __ipa_eth_refresh_device); mutex_init(ð_dev->refresh_mutex); INIT_LIST_HEAD(ð_dev->rx_channels); INIT_LIST_HEAD(ð_dev->tx_channels); Loading
drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_i.h +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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_
drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_offload.c +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
drivers/platform/msm/ipa/ipa_v3/ethernet/ipa_eth_utils.c 0 → 100644 +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; }