344 lines
13 KiB
Diff
344 lines
13 KiB
Diff
From f697e257f1481fdbbc7d4ac580ee606d2ee760c5 Mon Sep 17 00:00:00 2001
|
|
From: Huazhong Tan <tanhuazhong@huawei.com>
|
|
Date: Fri, 16 Jul 2021 13:23:28 +0800
|
|
Subject: [PATCH 038/283] net: hns3: add support for TX hardware checksum
|
|
offload
|
|
|
|
mainline inclusion
|
|
from mainline-v5.11-rc1
|
|
commit 66d52f3bf385c8d969e9ca6b281ddf773c9691d7
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EMQV
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=66d52f3bf385c8d969e9ca6b281ddf773c9691d7
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
For the device that supports TX hardware checksum, the hardware
|
|
can calculate the checksum from the start and fill the checksum
|
|
to the offset position, which reduces the operations of
|
|
calculating the type and header length of L3/L4. So add this
|
|
feature for the HNS3 ethernet driver.
|
|
|
|
The previous simple BD description is unsuitable, rename it as
|
|
HW TX CSUM.
|
|
|
|
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Reviewed-by: li yongxin <liyongxin1@huawei.com>
|
|
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
Signed-off-by: Xiaodong Li <lixiaodong67@huawei.com>
|
|
|
|
Conflicts:
|
|
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
|
|
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
---
|
|
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 6 +-
|
|
.../ethernet/hisilicon/hns3/hns3_debugfs.c | 2 +-
|
|
.../net/ethernet/hisilicon/hns3/hns3_enet.c | 63 +++++++++++++++----
|
|
.../net/ethernet/hisilicon/hns3/hns3_enet.h | 10 ++-
|
|
.../hisilicon/hns3/hns3pf/hclge_cmd.c | 2 +
|
|
.../hisilicon/hns3/hns3pf/hclge_cmd.h | 2 +-
|
|
.../hisilicon/hns3/hns3vf/hclgevf_cmd.c | 2 +
|
|
.../hisilicon/hns3/hns3vf/hclgevf_cmd.h | 2 +-
|
|
8 files changed, 71 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
|
|
index 7c00830b712e..509bf4f4de1d 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
|
|
@@ -83,7 +83,7 @@ enum HNAE3_DEV_CAP_BITS {
|
|
HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B,
|
|
HNAE3_DEV_SUPPORT_PTP_B,
|
|
HNAE3_DEV_SUPPORT_INT_QL_B,
|
|
- HNAE3_DEV_SUPPORT_SIMPLE_BD_B,
|
|
+ HNAE3_DEV_SUPPORT_HW_TX_CSUM_B,
|
|
HNAE3_DEV_SUPPORT_TX_PUSH_B,
|
|
HNAE3_DEV_SUPPORT_PHY_IMP_B,
|
|
HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B,
|
|
@@ -118,8 +118,8 @@ enum HNAE3_DEV_CAP_BITS {
|
|
#define hnae3_dev_int_ql_supported(hdev) \
|
|
test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, (hdev)->ae_dev->caps)
|
|
|
|
-#define hnae3_dev_simple_bd_supported(hdev) \
|
|
- test_bit(HNAE3_DEV_SUPPORT_SIMPLE_BD_B, (hdev)->ae_dev->caps)
|
|
+#define hnae3_dev_hw_csum_supported(hdev) \
|
|
+ test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, (hdev)->ae_dev->caps)
|
|
|
|
#define hnae3_dev_tx_push_supported(hdev) \
|
|
test_bit(HNAE3_DEV_SUPPORT_TX_PUSH_B, (hdev)->ae_dev->caps)
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
|
|
index 8dbbf597d8a2..59d9dda8f325 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
|
|
@@ -684,7 +684,7 @@ static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv,
|
|
le32_to_cpu(desc->tx.ol_type_vlan_len_msec));
|
|
sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen));
|
|
sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri));
|
|
- sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss));
|
|
+ sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum));
|
|
}
|
|
|
|
static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len)
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
index a06c01cd3efe..3e3c5b27567e 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
@@ -997,6 +997,22 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring,
|
|
return 0;
|
|
}
|
|
|
|
+/* check if the hardware is capable of checksum offloading */
|
|
+static bool hns3_check_hw_tx_csum(struct sk_buff *skb)
|
|
+{
|
|
+ struct hns3_nic_priv *priv = netdev_priv(skb->dev);
|
|
+
|
|
+ /* Kindly note, due to backward compatibility of the TX descriptor,
|
|
+ * HW checksum of the non-IP packets and GSO packets is handled at
|
|
+ * different place in the following code
|
|
+ */
|
|
+ if (skb->csum_not_inet || skb_is_gso(skb) ||
|
|
+ !test_bit(HNS3_NIC_STATE_HW_TX_CSUM_ENABLE, &priv->state))
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
|
|
struct sk_buff *skb, struct hns3_desc *desc,
|
|
struct hns3_desc_cb *desc_cb)
|
|
@@ -1004,9 +1020,9 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
|
|
u32 ol_type_vlan_len_msec = 0;
|
|
u32 type_cs_vlan_tso = 0;
|
|
u32 paylen = skb->len;
|
|
+ u16 mss_hw_csum = 0;
|
|
u16 inner_vtag = 0;
|
|
u16 out_vtag = 0;
|
|
- u16 mss = 0;
|
|
int ret;
|
|
|
|
ret = hns3_handle_vtags(ring, skb);
|
|
@@ -1033,6 +1049,17 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
|
|
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
|
u8 ol4_proto, il4_proto;
|
|
|
|
+ if (hns3_check_hw_tx_csum(skb)) {
|
|
+ /* set checksum start and offset, defined in 2 Bytes */
|
|
+ hns3_set_field(type_cs_vlan_tso, HNS3_TXD_CSUM_START_S,
|
|
+ skb_checksum_start_offset(skb) >> 1);
|
|
+ hns3_set_field(ol_type_vlan_len_msec,
|
|
+ HNS3_TXD_CSUM_OFFSET_S,
|
|
+ skb->csum_offset >> 1);
|
|
+ mss_hw_csum |= BIT(HNS3_TXD_HW_CS_B);
|
|
+ goto out_hw_tx_csum;
|
|
+ }
|
|
+
|
|
skb_reset_mac_len(skb);
|
|
|
|
ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto);
|
|
@@ -1053,7 +1080,7 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
|
|
return ret;
|
|
}
|
|
|
|
- ret = hns3_set_tso(skb, &paylen, &mss,
|
|
+ ret = hns3_set_tso(skb, &paylen, &mss_hw_csum,
|
|
&type_cs_vlan_tso, &desc_cb->send_bytes);
|
|
if (unlikely(ret < 0)) {
|
|
u64_stats_update_begin(&ring->syncp);
|
|
@@ -1063,12 +1090,13 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
|
|
}
|
|
}
|
|
|
|
+out_hw_tx_csum:
|
|
/* Set txbd */
|
|
desc->tx.ol_type_vlan_len_msec =
|
|
cpu_to_le32(ol_type_vlan_len_msec);
|
|
desc->tx.type_cs_vlan_tso_len = cpu_to_le32(type_cs_vlan_tso);
|
|
desc->tx.paylen = cpu_to_le32(paylen);
|
|
- desc->tx.mss = cpu_to_le16(mss);
|
|
+ desc->tx.mss_hw_csum = cpu_to_le16(mss_hw_csum);
|
|
desc->tx.vlan_tag = cpu_to_le16(inner_vtag);
|
|
desc->tx.outer_vlan_tag = cpu_to_le16(out_vtag);
|
|
|
|
@@ -2383,8 +2411,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|
|
|
netdev->priv_flags |= IFF_UNICAST_FLT;
|
|
|
|
- netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
|
- NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
+ netdev->hw_enc_features |= NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC |
|
|
@@ -2396,8 +2423,7 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|
netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
|
|
#endif
|
|
|
|
- netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
|
- NETIF_F_HW_VLAN_CTAG_FILTER |
|
|
+ netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
|
|
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
@@ -2405,16 +2431,15 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC |
|
|
NETIF_F_FRAGLIST;
|
|
|
|
- netdev->vlan_features |=
|
|
- NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
|
|
+ netdev->vlan_features |= NETIF_F_RXCSUM |
|
|
NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO |
|
|
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC |
|
|
NETIF_F_FRAGLIST;
|
|
|
|
- netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
|
- NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
|
|
+ netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
|
|
+ NETIF_F_HW_VLAN_CTAG_RX |
|
|
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
|
|
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
|
|
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
|
|
@@ -2438,6 +2463,18 @@ static void hns3_set_default_feature(struct net_device *netdev)
|
|
netdev->vlan_features |= NETIF_F_GSO_UDP_L4;
|
|
netdev->hw_enc_features |= NETIF_F_GSO_UDP_L4;
|
|
}
|
|
+
|
|
+ if (test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps)) {
|
|
+ netdev->hw_features |= NETIF_F_HW_CSUM;
|
|
+ netdev->features |= NETIF_F_HW_CSUM;
|
|
+ netdev->vlan_features |= NETIF_F_HW_CSUM;
|
|
+ netdev->hw_enc_features |= NETIF_F_HW_CSUM;
|
|
+ } else {
|
|
+ netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
|
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
|
+ netdev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
|
+ netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
|
|
+ }
|
|
}
|
|
|
|
static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
|
|
@@ -4147,6 +4184,7 @@ static void hns3_state_uninit(struct hnae3_handle *handle)
|
|
static int hns3_client_init(struct hnae3_handle *handle)
|
|
{
|
|
struct pci_dev *pdev = handle->pdev;
|
|
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
|
|
u16 alloc_tqps, max_rss_size;
|
|
struct hns3_nic_priv *priv;
|
|
struct net_device *netdev;
|
|
@@ -4243,6 +4281,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
|
|
netdev->max_mtu = HNS3_MAX_MTU;
|
|
#endif
|
|
|
|
+ if (test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps))
|
|
+ set_bit(HNS3_NIC_STATE_HW_TX_CSUM_ENABLE, &priv->state);
|
|
+
|
|
set_bit(HNS3_NIC_STATE_INITED, &priv->state);
|
|
|
|
ret = register_netdev(netdev);
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
index 0588642f906c..00a164343f0c 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
@@ -18,6 +18,7 @@ enum hns3_nic_state {
|
|
HNS3_NIC_STATE_SERVICE_INITED,
|
|
HNS3_NIC_STATE_SERVICE_SCHED,
|
|
HNS3_NIC_STATE2_RESET_REQUESTED,
|
|
+ HNS3_NIC_STATE_HW_TX_CSUM_ENABLE,
|
|
HNS3_NIC_STATE_MAX
|
|
};
|
|
|
|
@@ -142,6 +143,9 @@ enum hns3_nic_state {
|
|
#define HNS3_TXD_L4LEN_S 24
|
|
#define HNS3_TXD_L4LEN_M (0xff << HNS3_TXD_L4LEN_S)
|
|
|
|
+#define HNS3_TXD_CSUM_START_S 8
|
|
+#define HNS3_TXD_CSUM_START_M (0xffff << HNS3_TXD_CSUM_START_S)
|
|
+
|
|
#define HNS3_TXD_OL3T_S 0
|
|
#define HNS3_TXD_OL3T_M (0x3 << HNS3_TXD_OL3T_S)
|
|
#define HNS3_TXD_OVLAN_B 2
|
|
@@ -149,6 +153,9 @@ enum hns3_nic_state {
|
|
#define HNS3_TXD_TUNTYPE_S 4
|
|
#define HNS3_TXD_TUNTYPE_M (0xf << HNS3_TXD_TUNTYPE_S)
|
|
|
|
+#define HNS3_TXD_CSUM_OFFSET_S 8
|
|
+#define HNS3_TXD_CSUM_OFFSET_M (0xffff << HNS3_TXD_CSUM_OFFSET_S)
|
|
+
|
|
#define HNS3_TXD_BDTYPE_S 0
|
|
#define HNS3_TXD_BDTYPE_M (0xf << HNS3_TXD_BDTYPE_S)
|
|
#define HNS3_TXD_FE_B 4
|
|
@@ -164,6 +171,7 @@ enum hns3_nic_state {
|
|
|
|
#define HNS3_TXD_MSS_S 0
|
|
#define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S)
|
|
+#define HNS3_TXD_HW_CS_B 14
|
|
|
|
#define HNS3_VECTOR_TX_IRQ BIT_ULL(0)
|
|
#define HNS3_VECTOR_RX_IRQ BIT_ULL(1)
|
|
@@ -254,7 +262,7 @@ struct __packed hns3_desc {
|
|
|
|
__le32 paylen;
|
|
__le16 bdtp_fe_sc_vld_ra_ri;
|
|
- __le16 mss;
|
|
+ __le16 mss_hw_csum;
|
|
} tx;
|
|
|
|
struct {
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
|
|
index d1e963195259..1b986185d145 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
|
|
@@ -371,6 +371,8 @@ static void hclge_parse_capability(struct hclge_dev *hdev,
|
|
set_bit(HNAE3_DEV_SUPPORT_INT_QL_B, ae_dev->caps);
|
|
if (hnae3_get_bit(caps, HCLGE_CAP_TQP_TXRX_INDEP_B))
|
|
set_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, ae_dev->caps);
|
|
+ if (hnae3_get_bit(caps, HCLGE_CAP_HW_TX_CSUM_B))
|
|
+ set_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps);
|
|
}
|
|
|
|
static enum hclge_cmd_status
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
|
|
index bd4238f3009c..ed737e7d740a 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
|
|
@@ -375,7 +375,7 @@ enum HCLGE_CAP_BITS {
|
|
HCLGE_CAP_FD_FORWARD_TC_B,
|
|
HCLGE_CAP_PTP_B,
|
|
HCLGE_CAP_INT_QL_B,
|
|
- HCLGE_CAP_SIMPLE_BD_B,
|
|
+ HCLGE_CAP_HW_TX_CSUM_B,
|
|
HCLGE_CAP_TX_PUSH_B,
|
|
HCLGE_CAP_PHY_IMP_B,
|
|
HCLGE_CAP_TQP_TXRX_INDEP_B,
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
|
|
index d120211c3ef5..d0bbbf213d06 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
|
|
@@ -352,6 +352,8 @@ static void hclgevf_parse_capability(struct hclgevf_dev *hdev,
|
|
set_bit(HNAE3_DEV_SUPPORT_INT_QL_B, ae_dev->caps);
|
|
if (hnae3_get_bit(caps, HCLGEVF_CAP_TQP_TXRX_INDEP_B))
|
|
set_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, ae_dev->caps);
|
|
+ if (hnae3_get_bit(caps, HCLGEVF_CAP_HW_TX_CSUM_B))
|
|
+ set_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps);
|
|
}
|
|
|
|
static int hclgevf_cmd_query_version_and_capability(struct hclgevf_dev *hdev)
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
|
|
index 0d1690d9fecf..40632d8b6d79 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
|
|
@@ -148,7 +148,7 @@ enum HCLGEVF_CAP_BITS {
|
|
HCLGEVF_CAP_FD_FORWARD_TC_B,
|
|
HCLGEVF_CAP_PTP_B,
|
|
HCLGEVF_CAP_INT_QL_B,
|
|
- HCLGEVF_CAP_SIMPLE_BD_B,
|
|
+ HCLGEVF_CAP_HW_TX_CSUM_B,
|
|
HCLGEVF_CAP_TX_PUSH_B,
|
|
HCLGEVF_CAP_PHY_IMP_B,
|
|
HCLGEVF_CAP_TQP_TXRX_INDEP_B,
|
|
--
|
|
2.34.1
|
|
|