diff options
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index be425ad5e824..6b7e21a8da57 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -633,32 +633,6 @@ enum rtl_tx_desc_bit_1 { | |||
633 | TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ | 633 | TD1_UDP_CS = (1 << 31), /* Calculate UDP/IP checksum */ |
634 | }; | 634 | }; |
635 | 635 | ||
636 | static const struct rtl_tx_desc_info { | ||
637 | struct { | ||
638 | u32 udp; | ||
639 | u32 tcp; | ||
640 | } checksum; | ||
641 | u16 mss_shift; | ||
642 | u16 opts_offset; | ||
643 | } tx_desc_info [] = { | ||
644 | [RTL_TD_0] = { | ||
645 | .checksum = { | ||
646 | .udp = TD0_IP_CS | TD0_UDP_CS, | ||
647 | .tcp = TD0_IP_CS | TD0_TCP_CS | ||
648 | }, | ||
649 | .mss_shift = TD0_MSS_SHIFT, | ||
650 | .opts_offset = 0 | ||
651 | }, | ||
652 | [RTL_TD_1] = { | ||
653 | .checksum = { | ||
654 | .udp = TD1_IP_CS | TD1_UDP_CS, | ||
655 | .tcp = TD1_IP_CS | TD1_TCP_CS | ||
656 | }, | ||
657 | .mss_shift = TD1_MSS_SHIFT, | ||
658 | .opts_offset = 1 | ||
659 | } | ||
660 | }; | ||
661 | |||
662 | enum rtl_rx_desc_bit { | 636 | enum rtl_rx_desc_bit { |
663 | /* Rx private */ | 637 | /* Rx private */ |
664 | PID1 = (1 << 18), /* Protocol ID bit 1/2 */ | 638 | PID1 = (1 << 18), /* Protocol ID bit 1/2 */ |
@@ -782,6 +756,7 @@ struct rtl8169_private { | |||
782 | unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); | 756 | unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); |
783 | unsigned int (*link_ok)(void __iomem *); | 757 | unsigned int (*link_ok)(void __iomem *); |
784 | int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); | 758 | int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); |
759 | bool (*tso_csum)(struct rtl8169_private *, struct sk_buff *, u32 *); | ||
785 | 760 | ||
786 | struct { | 761 | struct { |
787 | DECLARE_BITMAP(flags, RTL_FLAG_MAX); | 762 | DECLARE_BITMAP(flags, RTL_FLAG_MAX); |
@@ -5941,16 +5916,36 @@ static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) | |||
5941 | return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; | 5916 | return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; |
5942 | } | 5917 | } |
5943 | 5918 | ||
5944 | static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, | 5919 | static bool rtl8169_tso_csum_v1(struct rtl8169_private *tp, |
5945 | struct sk_buff *skb, u32 *opts) | 5920 | struct sk_buff *skb, u32 *opts) |
5946 | { | 5921 | { |
5947 | const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; | ||
5948 | u32 mss = skb_shinfo(skb)->gso_size; | 5922 | u32 mss = skb_shinfo(skb)->gso_size; |
5949 | int offset = info->opts_offset; | ||
5950 | 5923 | ||
5951 | if (mss) { | 5924 | if (mss) { |
5952 | opts[0] |= TD_LSO; | 5925 | opts[0] |= TD_LSO; |
5953 | opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift; | 5926 | opts[0] |= min(mss, TD_MSS_MAX) << TD0_MSS_SHIFT; |
5927 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
5928 | const struct iphdr *ip = ip_hdr(skb); | ||
5929 | |||
5930 | if (ip->protocol == IPPROTO_TCP) | ||
5931 | opts[0] |= TD0_IP_CS | TD0_TCP_CS; | ||
5932 | else if (ip->protocol == IPPROTO_UDP) | ||
5933 | opts[0] |= TD0_IP_CS | TD0_UDP_CS; | ||
5934 | else | ||
5935 | WARN_ON_ONCE(1); | ||
5936 | } | ||
5937 | |||
5938 | return true; | ||
5939 | } | ||
5940 | |||
5941 | static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, | ||
5942 | struct sk_buff *skb, u32 *opts) | ||
5943 | { | ||
5944 | u32 mss = skb_shinfo(skb)->gso_size; | ||
5945 | |||
5946 | if (mss) { | ||
5947 | opts[0] |= TD_LSO; | ||
5948 | opts[1] |= min(mss, TD_MSS_MAX) << TD1_MSS_SHIFT; | ||
5954 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | 5949 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
5955 | const struct iphdr *ip = ip_hdr(skb); | 5950 | const struct iphdr *ip = ip_hdr(skb); |
5956 | 5951 | ||
@@ -5958,15 +5953,16 @@ static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, | |||
5958 | return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); | 5953 | return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); |
5959 | 5954 | ||
5960 | if (ip->protocol == IPPROTO_TCP) | 5955 | if (ip->protocol == IPPROTO_TCP) |
5961 | opts[offset] |= info->checksum.tcp; | 5956 | opts[1] |= TD1_IP_CS | TD1_TCP_CS; |
5962 | else if (ip->protocol == IPPROTO_UDP) | 5957 | else if (ip->protocol == IPPROTO_UDP) |
5963 | opts[offset] |= info->checksum.udp; | 5958 | opts[1] |= TD1_IP_CS | TD1_UDP_CS; |
5964 | else | 5959 | else |
5965 | WARN_ON_ONCE(1); | 5960 | WARN_ON_ONCE(1); |
5966 | } else { | 5961 | } else { |
5967 | if (unlikely(rtl_test_hw_pad_bug(tp, skb))) | 5962 | if (unlikely(rtl_test_hw_pad_bug(tp, skb))) |
5968 | return rtl_skb_pad(skb); | 5963 | return rtl_skb_pad(skb); |
5969 | } | 5964 | } |
5965 | |||
5970 | return true; | 5966 | return true; |
5971 | } | 5967 | } |
5972 | 5968 | ||
@@ -5994,7 +5990,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
5994 | opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); | 5990 | opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(skb)); |
5995 | opts[0] = DescOwn; | 5991 | opts[0] = DescOwn; |
5996 | 5992 | ||
5997 | if (!rtl8169_tso_csum(tp, skb, opts)) | 5993 | if (!tp->tso_csum(tp, skb, opts)) |
5998 | goto err_update_stats; | 5994 | goto err_update_stats; |
5999 | 5995 | ||
6000 | len = skb_headlen(skb); | 5996 | len = skb_headlen(skb); |
@@ -7145,6 +7141,13 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7145 | /* 8110SCd requires hardware Rx VLAN - disallow toggling */ | 7141 | /* 8110SCd requires hardware Rx VLAN - disallow toggling */ |
7146 | dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX; | 7142 | dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX; |
7147 | 7143 | ||
7144 | if (tp->txd_version == RTL_TD_0) | ||
7145 | tp->tso_csum = rtl8169_tso_csum_v1; | ||
7146 | else if (tp->txd_version == RTL_TD_1) | ||
7147 | tp->tso_csum = rtl8169_tso_csum_v2; | ||
7148 | else | ||
7149 | WARN_ON_ONCE(1); | ||
7150 | |||
7148 | dev->hw_features |= NETIF_F_RXALL; | 7151 | dev->hw_features |= NETIF_F_RXALL; |
7149 | dev->hw_features |= NETIF_F_RXFCS; | 7152 | dev->hw_features |= NETIF_F_RXFCS; |
7150 | 7153 | ||