diff options
author | hayeswang <hayeswang@realtek.com> | 2015-01-06 10:41:58 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-06 19:29:13 +0100 |
commit | a5e31255e02a0797259f210c3bb92c6326a98a9c (patch) | |
tree | 6b3d7dcb1c643376d7af160340aaafd770b69f3e /drivers/net/usb/r8152.c | |
parent | net: ethernet: cpsw: fix hangs with interrupts (diff) | |
download | linux-a5e31255e02a0797259f210c3bb92c6326a98a9c.tar.xz linux-a5e31255e02a0797259f210c3bb92c6326a98a9c.zip |
r8152: support ndo_features_check
Support ndo_features_check to avoid:
- the transport offset is more than the hw limitation when using hw checksum.
- the skb->len of a GSO packet is more than the limitation.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | drivers/net/usb/r8152.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 2d1c77e81836..57ec23e8ccfa 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1897,6 +1897,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) netif_wake_queue(netdev); } +static netdev_features_t +rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, + netdev_features_t features) +{ + u32 mss = skb_shinfo(skb)->gso_size; + int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; + int offset = skb_transport_offset(skb); + + if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) + features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); + else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) + features &= ~NETIF_F_GSO_MASK; + + return features; +} + static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, struct net_device *netdev) { @@ -3706,6 +3722,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { .ndo_set_mac_address = rtl8152_set_mac_address, .ndo_change_mtu = rtl8152_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_features_check = rtl8152_features_check, }; static void r8152b_get_version(struct r8152 *tp) |