Skip to content

Commit 773235f

Browse files
hkallweitdavem330
authored andcommitted
r8169: add workaround for RTL8168evl TSO hw issues
Add workaround for hw issues with TSO on RTL8168evl. This workaround is based on information I got from Realtek, and *should* allow to safely enable TSO on this chip version. Signed-off-by: Heiner Kallweit <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0623b98 commit 773235f

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

drivers/net/ethernet/realtek/r8169_main.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4306,6 +4306,37 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
43064306
return NETDEV_TX_BUSY;
43074307
}
43084308

4309+
static unsigned int rtl_last_frag_len(struct sk_buff *skb)
4310+
{
4311+
struct skb_shared_info *info = skb_shinfo(skb);
4312+
unsigned int nr_frags = info->nr_frags;
4313+
4314+
if (!nr_frags)
4315+
return UINT_MAX;
4316+
4317+
return skb_frag_size(info->frags + nr_frags - 1);
4318+
}
4319+
4320+
/* Workaround for hw issues with TSO on RTL8168evl */
4321+
static netdev_features_t rtl8168evl_fix_tso(struct sk_buff *skb,
4322+
netdev_features_t features)
4323+
{
4324+
/* IPv4 header has options field */
4325+
if (vlan_get_protocol(skb) == htons(ETH_P_IP) &&
4326+
ip_hdrlen(skb) > sizeof(struct iphdr))
4327+
features &= ~NETIF_F_ALL_TSO;
4328+
4329+
/* IPv4 TCP header has options field */
4330+
else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 &&
4331+
tcp_hdrlen(skb) > sizeof(struct tcphdr))
4332+
features &= ~NETIF_F_ALL_TSO;
4333+
4334+
else if (rtl_last_frag_len(skb) <= 6)
4335+
features &= ~NETIF_F_ALL_TSO;
4336+
4337+
return features;
4338+
}
4339+
43094340
static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
43104341
struct net_device *dev,
43114342
netdev_features_t features)
@@ -4314,6 +4345,9 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
43144345
struct rtl8169_private *tp = netdev_priv(dev);
43154346

43164347
if (skb_is_gso(skb)) {
4348+
if (tp->mac_version == RTL_GIGA_MAC_VER_34)
4349+
features = rtl8168evl_fix_tso(skb, features);
4350+
43174351
if (transport_offset > GTTCPHO_MAX &&
43184352
rtl_chip_supports_csum_v2(tp))
43194353
features &= ~NETIF_F_ALL_TSO;

0 commit comments

Comments
 (0)