diff options
Diffstat (limited to 'target/linux/generic/patches-4.0/761-8139cp-fixes-from-4.4.patch')
-rw-r--r-- | target/linux/generic/patches-4.0/761-8139cp-fixes-from-4.4.patch | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/target/linux/generic/patches-4.0/761-8139cp-fixes-from-4.4.patch b/target/linux/generic/patches-4.0/761-8139cp-fixes-from-4.4.patch new file mode 100644 index 0000000000..cb605e531c --- /dev/null +++ b/target/linux/generic/patches-4.0/761-8139cp-fixes-from-4.4.patch @@ -0,0 +1,105 @@ +commit 8b7a7048220f86547db31de0abe1ea6dd2cfa892 +Author: David Woodhouse <dwmw2@infradead.org> +Date: Thu Sep 24 11:38:22 2015 +0100 + + 8139cp: Fix GSO MSS handling + + When fixing the TSO support I noticed we just mask ->gso_size with the + MSSMask value and don't care about the consequences. + + Provide a .ndo_features_check() method which drops the NETIF_F_TSO + feature for any skb which would exceed the maximum, and thus forces it + to be segmented by software. + + Then we can stop the masking in cp_start_xmit(), and just WARN if the + maximum is exceeded, which should now never happen. + + Finally, Francois Romieu noticed that we didn't even have the right + value for MSSMask anyway; it should be 0x7ff (11 bits) not 0xfff. + + Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> + Signed-off-by: David S. Miller <davem@davemloft.net> + +commit 5a58f227790faded5a3ef6075f3ddd65093e0f86 +Author: David Woodhouse <David.Woodhouse@intel.com> +Date: Wed Sep 23 09:46:09 2015 +0100 + + 8139cp: Enable offload features by default + + I fixed TSO. Hardware checksum and scatter/gather also appear to be + working correctly both on real hardware and in QEMU's emulation. + + Let's enable them by default and see if anyone screams... + + Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> + Signed-off-by: David S. Miller <davem@davemloft.net> +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index 686334f..deae10d 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -175,7 +175,7 @@ enum { + LastFrag = (1 << 28), /* Final segment of a packet */ + LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ + MSSShift = 16, /* MSS value position */ +- MSSMask = 0xfff, /* MSS value: 11 bits */ ++ MSSMask = 0x7ff, /* MSS value: 11 bits */ + TxError = (1 << 23), /* Tx error summary */ + RxError = (1 << 20), /* Rx error summary */ + IPCS = (1 << 18), /* Calculate IP checksum */ +@@ -754,10 +754,16 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, + eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; + mss = skb_shinfo(skb)->gso_size; + ++ if (mss > MSSMask) { ++ WARN_ONCE(1, "Net bug: GSO size %d too large for 8139CP\n", ++ mss); ++ goto out_dma_error; ++ } ++ + opts2 = cpu_to_le32(cp_tx_vlan_tag(skb)); + opts1 = DescOwn; + if (mss) +- opts1 |= LargeSend | ((mss & MSSMask) << MSSShift); ++ opts1 |= LargeSend | (mss << MSSShift); + else if (skb->ip_summed == CHECKSUM_PARTIAL) { + const struct iphdr *ip = ip_hdr(skb); + if (ip->protocol == IPPROTO_TCP) +@@ -1852,6 +1858,15 @@ static void cp_set_d3_state (struct cp_private *cp) + pci_set_power_state (cp->pdev, PCI_D3hot); + } + ++static netdev_features_t cp_features_check(struct sk_buff *skb, ++ struct net_device *dev, ++ netdev_features_t features) ++{ ++ if (skb_shinfo(skb)->gso_size > MSSMask) ++ features &= ~NETIF_F_TSO; ++ ++ return vlan_features_check(skb, features); ++} + static const struct net_device_ops cp_netdev_ops = { + .ndo_open = cp_open, + .ndo_stop = cp_close, +@@ -1864,6 +1879,7 @@ static const struct net_device_ops cp_netdev_ops = { + .ndo_tx_timeout = cp_tx_timeout, + .ndo_set_features = cp_set_features, + .ndo_change_mtu = cp_change_mtu, ++ .ndo_features_check = cp_features_check, + + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = cp_poll_controller, +@@ -1983,12 +1999,12 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) + dev->ethtool_ops = &cp_ethtool_ops; + dev->watchdog_timeo = TX_TIMEOUT; + +- dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; ++ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | ++ NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + + if (pci_using_dac) + dev->features |= NETIF_F_HIGHDMA; + +- /* disabled by default until verified */ + dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | |