From a62e95672d01802572179da1323c18e943ffc281 Mon Sep 17 00:00:00 2001 From: Jiyoung Jeong Date: Tue, 23 Oct 2018 21:15:38 +0900 Subject: [PATCH] [9610] drivers: modem_if: Add GRO to SIT modem interface Change-Id: I1a1e3d83b703ec39be3d11f789f5e2f0acfc0221 Signed-off-by: Jiyoung Jeong --- drivers/misc/modem_if/Kconfig | 7 +++ drivers/misc/modem_if/modem_io_device.c | 52 +++++++++++++++++-- .../misc/modem_if/modem_link_device_shmem.c | 29 +++++++++++ .../misc/modem_if/modem_link_device_shmem.h | 4 ++ drivers/misc/modem_if/modem_prj.h | 4 ++ 5 files changed, 91 insertions(+), 5 deletions(-) diff --git a/drivers/misc/modem_if/Kconfig b/drivers/misc/modem_if/Kconfig index d17d6bcd4b11..adcc42f9f530 100644 --- a/drivers/misc/modem_if/Kconfig +++ b/drivers/misc/modem_if/Kconfig @@ -49,6 +49,13 @@ config MODEM_IF_ADAPTIVE_QOS bool "Enable Adaptive QOS for high data performance" default n +config MODEM_IF_NET_GRO + bool "enable GRO feature" + depends on LINK_DEVICE_NAPI + default n + ---help--- + This enables GRO(Generic Receive Offload) feature + config UART_SWITCH bool "UART SWITCH Support" default n diff --git a/drivers/misc/modem_if/modem_io_device.c b/drivers/misc/modem_if/modem_io_device.c index 7394ef7bab04..b93738ae2edf 100644 --- a/drivers/misc/modem_if/modem_io_device.c +++ b/drivers/misc/modem_if/modem_io_device.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,7 @@ #include "modem_prj.h" #include "modem_utils.h" - +#include "modem_link_device_shmem.h" static u16 exynos_build_fr_config(struct io_device *iod, struct link_device *ld, unsigned int count); @@ -311,12 +312,34 @@ static int rx_raw_misc(struct sk_buff *skb) return 0; } +#ifdef CONFIG_LINK_DEVICE_NAPI +#ifdef CONFIG_MODEM_IF_NET_GRO +static int check_gro_support(struct sk_buff *skb) +{ + switch (skb->data[0] & 0xF0) { + case 0x40: + return (ip_hdr(skb)->protocol == IPPROTO_TCP); + + case 0x60: + return (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP); + } + return 0; +} +#else +static int check_gro_support(struct sk_buff *skb) +{ + return 0; +} +#endif +#endif + static int rx_multi_pdp(struct sk_buff *skb) { struct link_device *ld = skbpriv(skb)->ld; struct io_device *iod = skbpriv(skb)->iod; struct net_device *ndev; struct iphdr *iphdr; + struct shmem_link_device *shmd = to_shmem_link_device(ld); int ret; ndev = iod->ndev; @@ -353,10 +376,23 @@ static int rx_multi_pdp(struct sk_buff *skb) } #ifdef CONFIG_LINK_DEVICE_NAPI - ret = netif_receive_skb(skb); - if (ret != NET_RX_SUCCESS) { - mif_err("%s->%s: ERR! netif_receive_skb (err %d)\n", - ld->name, iod->name, ret); + skb_reset_network_header(skb); + + if (check_gro_support(skb)) { + ret = napi_gro_receive(&shmd->mld_napi, skb); + if (ret == GRO_DROP) { + mif_err_limited("%s: %s<-%s: ERR! napi_gro_receive\n", + ld->name, iod->name, iod->mc->name); + } + + if (ld->gro_flush) + ld->gro_flush(ld); + } else { + ret = netif_receive_skb(skb); + if (ret != NET_RX_SUCCESS) { + mif_err_limited("%s->%s: ERR! netif_receive_skb (err %d)\n", + ld->name, iod->name, ret); + } } #else /* !CONFIG_LINK_DEVICE_NAPI */ if (in_interrupt()) @@ -1546,6 +1582,9 @@ static void vnet_setup(struct net_device *ndev) ndev->tx_queue_len = 1000; ndev->mtu = ETH_DATA_LEN; ndev->watchdog_timeo = 5 * HZ; +#ifdef CONFIG_MODEM_IF_NET_GRO + ndev->features |= NETIF_F_GRO; +#endif } static void vnet_setup_ether(struct net_device *ndev) @@ -1559,6 +1598,9 @@ static void vnet_setup_ether(struct net_device *ndev) ndev->tx_queue_len = 1000; ndev->mtu = ETH_DATA_LEN; ndev->watchdog_timeo = 5 * HZ; +#ifdef CONFIG_MODEM_IF_NET_GRO + ndev->features |= NETIF_F_GRO; +#endif } static u16 exynos_build_fr_config(struct io_device *iod, struct link_device *ld, diff --git a/drivers/misc/modem_if/modem_link_device_shmem.c b/drivers/misc/modem_if/modem_link_device_shmem.c index d87a8a08399b..3c4ed5fed949 100644 --- a/drivers/misc/modem_if/modem_link_device_shmem.c +++ b/drivers/misc/modem_if/modem_link_device_shmem.c @@ -2526,6 +2526,31 @@ static int shmem_crash_reason(struct link_device *ld, struct io_device *iod, return 0; } +#ifdef CONFIG_MODEM_IF_NET_GRO +static long gro_flush_time = 100000L; +module_param(gro_flush_time, long, 0644); + +static void gro_flush_timer(struct link_device *ld) +{ + struct shmem_link_device *shmd = to_shmem_link_device(ld); + struct timespec curr, diff; + + if (!gro_flush_time) + return; + + if (unlikely(shmd->flush_time.tv_sec == 0)) { + getnstimeofday(&shmd->flush_time); + } else { + getnstimeofday(&(curr)); + diff = timespec_sub(curr, shmd->flush_time); + if ((diff.tv_sec > 0) || (diff.tv_nsec > gro_flush_time)) { + napi_gro_flush(&shmd->mld_napi, false); + getnstimeofday(&shmd->flush_time); + } + } +} +#endif + #ifdef CONFIG_LINK_DEVICE_NAPI /* * shmd_rx_int_poll @@ -2806,6 +2831,10 @@ struct link_device *shmem_create_link_device(struct platform_device *pdev) ld->acpm_dump = save_acpm_dump; ld->crash_reason = shmem_crash_reason; +#ifdef CONFIG_MODEM_IF_NET_GRO + ld->gro_flush = gro_flush_timer; +#endif + #ifdef CONFIG_LINK_DEVICE_NAPI ld->enable_rx_int = shmem_enable_rx_int; ld->disable_rx_int = shmem_disable_rx_int; diff --git a/drivers/misc/modem_if/modem_link_device_shmem.h b/drivers/misc/modem_if/modem_link_device_shmem.h index 5fb757a19f35..2a3e3ac0c6f1 100644 --- a/drivers/misc/modem_if/modem_link_device_shmem.h +++ b/drivers/misc/modem_if/modem_link_device_shmem.h @@ -237,6 +237,10 @@ struct shmem_link_device { unsigned int rx_poll_count; unsigned long long rx_int_disabled_time; #endif /* CONFIG_LINK_DEVICE_NAPI */ + +#ifdef CONFIG_MODEM_IF_NET_GRO + struct timespec flush_time; +#endif }; /* converts from struct link_device* to struct xxx_link_device* */ diff --git a/drivers/misc/modem_if/modem_prj.h b/drivers/misc/modem_if/modem_prj.h index a97977e32e6f..9f7660fec193 100644 --- a/drivers/misc/modem_if/modem_prj.h +++ b/drivers/misc/modem_if/modem_prj.h @@ -25,6 +25,9 @@ #include #include #include +#include +#include + #include "include/modem_v1.h" #include "include/exynos_ipc.h" @@ -650,6 +653,7 @@ struct link_device { int (*enable_rx_int)(struct link_device *ld); int (*disable_rx_int)(struct link_device *ld); #endif /* CONFIG_LINK_DEVICE_NAPI */ + void (*gro_flush)(struct link_device *ld); }; /** rx_alloc_skb - allocate an skbuff and set skb's iod, ld -- 2.20.1