[dpdk-stable] [PATCH 14/24] net/hns3: support LRO
Wei Hu (Xavier)
huwei013 at chinasoftinc.com
Mon Aug 17 11:25:22 CEST 2020
From: "Wei Hu (Xavier)" <xavier.huwei at huawei.com>
[ upstream commit 1f295c40da3de1722ed6f6f0bc0853966b6ff4ae ]
This patch adds support of LRO offload for hns3 PMD driver.
Signed-off-by: Hongbo Zheng <zhenghongbo3 at huawei.com>
Signed-off-by: Wei Hu (Xavier) <xavier.huwei at huawei.com>
---
doc/guides/nics/features/hns3.ini | 1 +
doc/guides/nics/features/hns3_vf.ini | 1 +
doc/guides/nics/hns3.rst | 1 +
drivers/net/hns3/hns3_ethdev.c | 35 ++++++++++------------
drivers/net/hns3/hns3_ethdev.h | 2 +-
drivers/net/hns3/hns3_ethdev_vf.c | 16 +++++++++-
drivers/net/hns3/hns3_rxtx.c | 45 ++++++++++++++++++++++++++++
drivers/net/hns3/hns3_rxtx.h | 4 ++-
8 files changed, 82 insertions(+), 23 deletions(-)
diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini
index c3a8544bc..66abda7cb 100644
--- a/doc/guides/nics/features/hns3.ini
+++ b/doc/guides/nics/features/hns3.ini
@@ -9,6 +9,7 @@ Rx interrupt = Y
MTU update = Y
Jumbo frame = Y
TSO = Y
+LRO = Y
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
diff --git a/doc/guides/nics/features/hns3_vf.ini b/doc/guides/nics/features/hns3_vf.ini
index 80773ac90..71d246afc 100644
--- a/doc/guides/nics/features/hns3_vf.ini
+++ b/doc/guides/nics/features/hns3_vf.ini
@@ -9,6 +9,7 @@ Rx interrupt = Y
MTU update = Y
Jumbo frame = Y
TSO = Y
+LRO = Y
Promiscuous mode = Y
Allmulticast mode = Y
Unicast MAC filter = Y
diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 05dbe4174..ae3c5f63f 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -18,6 +18,7 @@ Features of the HNS3 PMD are:
- Packet type information
- Checksum offload
- TSO offload
+- LRO offload
- Promiscuous mode
- Multicast mode
- Port hardware statistics
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index fcd47ef9a..fc5db2aaf 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -1096,25 +1096,6 @@ hns3_config_tso(struct hns3_hw *hw, unsigned int tso_mss_min,
return hns3_cmd_send(hw, &desc, 1);
}
-int
-hns3_config_gro(struct hns3_hw *hw, bool en)
-{
- struct hns3_cfg_gro_status_cmd *req;
- struct hns3_cmd_desc desc;
- int ret;
-
- hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GRO_GENERIC_CONFIG, false);
- req = (struct hns3_cfg_gro_status_cmd *)desc.data;
-
- req->gro_en = rte_cpu_to_le_16(en ? 1 : 0);
-
- ret = hns3_cmd_send(hw, &desc, 1);
- if (ret)
- hns3_err(hw, "GRO hardware config cmd failed, ret = %d", ret);
-
- return ret;
-}
-
static int
hns3_set_umv_space(struct hns3_hw *hw, uint16_t space_size,
uint16_t *allocated_size, bool is_alloc)
@@ -2281,6 +2262,7 @@ hns3_dev_configure(struct rte_eth_dev *dev)
uint16_t nb_tx_q = dev->data->nb_tx_queues;
struct rte_eth_rss_conf rss_conf;
uint16_t mtu;
+ bool gro_en;
int ret;
/*
@@ -2347,6 +2329,12 @@ hns3_dev_configure(struct rte_eth_dev *dev)
if (ret)
goto cfg_err;
+ /* config hardware GRO */
+ gro_en = conf->rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false;
+ ret = hns3_config_gro(hw, gro_en);
+ if (ret)
+ goto cfg_err;
+
hw->adapter_state = HNS3_NIC_CONFIGURED;
return 0;
@@ -2456,6 +2444,7 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
info->min_rx_bufsize = HNS3_MIN_BD_BUF_SIZE;
info->max_mac_addrs = HNS3_UC_MACADDR_NUM;
info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD;
+ info->max_lro_pkt_size = HNS3_MAX_LRO_SIZE;
info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM |
DEV_RX_OFFLOAD_TCP_CKSUM |
DEV_RX_OFFLOAD_UDP_CKSUM |
@@ -2467,7 +2456,8 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
DEV_RX_OFFLOAD_VLAN_STRIP |
DEV_RX_OFFLOAD_VLAN_FILTER |
DEV_RX_OFFLOAD_JUMBO_FRAME |
- DEV_RX_OFFLOAD_RSS_HASH);
+ DEV_RX_OFFLOAD_RSS_HASH |
+ DEV_RX_OFFLOAD_TCP_LRO);
info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
DEV_TX_OFFLOAD_IPV4_CKSUM |
@@ -4414,6 +4404,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev)
hns3_enable_hw_error_intr(hns, false);
hns3_rss_uninit(hns);
+ (void)hns3_config_gro(hw, false);
hns3_promisc_uninit(hw);
hns3_fdir_filter_uninit(hns);
hns3_uninit_umv_space(hw);
@@ -5249,6 +5240,10 @@ hns3_restore_conf(struct hns3_adapter *hns)
if (ret)
goto err_promisc;
+ ret = hns3_restore_gro_conf(hw);
+ if (ret)
+ goto err_promisc;
+
if (hns->hw.adapter_state == HNS3_NIC_STARTED) {
ret = hns3_do_start(hns, false);
if (ret)
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index ba06ed103..c98e810fb 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -44,6 +44,7 @@
#define HNS3_MAX_BD_PAYLEN (1024 * 1024 - 1)
#define HNS3_MAX_TSO_HDR_SIZE 512
#define HNS3_MAX_TSO_HDR_BD_NUM 3
+#define HNS3_MAX_LRO_SIZE 64512
#define HNS3_ETH_OVERHEAD \
(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + HNS3_VLAN_TAG_SIZE * 2)
@@ -651,7 +652,6 @@ hns3_test_and_clear_bit(unsigned int nr, volatile uint64_t *addr)
}
int hns3_buffer_alloc(struct hns3_hw *hw);
-int hns3_config_gro(struct hns3_hw *hw, bool en);
int hns3_dev_filter_ctrl(struct rte_eth_dev *dev,
enum rte_filter_type filter_type,
enum rte_filter_op filter_op, void *arg);
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 99e09ec45..0fff7a42b 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -765,6 +765,7 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
uint16_t nb_tx_q = dev->data->nb_tx_queues;
struct rte_eth_rss_conf rss_conf;
uint16_t mtu;
+ bool gro_en;
int ret;
/*
@@ -825,6 +826,12 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
if (ret)
goto cfg_err;
+ /* config hardware GRO */
+ gro_en = conf->rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false;
+ ret = hns3_config_gro(hw, gro_en);
+ if (ret)
+ goto cfg_err;
+
hw->adapter_state = HNS3_NIC_CONFIGURED;
return 0;
@@ -906,6 +913,7 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
info->min_rx_bufsize = HNS3_MIN_BD_BUF_SIZE;
info->max_mac_addrs = HNS3_VF_UC_MACADDR_NUM;
info->max_mtu = info->max_rx_pktlen - HNS3_ETH_OVERHEAD;
+ info->max_lro_pkt_size = HNS3_MAX_LRO_SIZE;
info->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM |
DEV_RX_OFFLOAD_UDP_CKSUM |
@@ -918,7 +926,8 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
DEV_RX_OFFLOAD_VLAN_STRIP |
DEV_RX_OFFLOAD_VLAN_FILTER |
DEV_RX_OFFLOAD_JUMBO_FRAME |
- DEV_RX_OFFLOAD_RSS_HASH);
+ DEV_RX_OFFLOAD_RSS_HASH |
+ DEV_RX_OFFLOAD_TCP_LRO);
info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
info->tx_offload_capa = (DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
DEV_TX_OFFLOAD_IPV4_CKSUM |
@@ -1654,6 +1663,7 @@ hns3vf_uninit_vf(struct rte_eth_dev *eth_dev)
PMD_INIT_FUNC_TRACE();
hns3_rss_uninit(hns);
+ (void)hns3_config_gro(hw, false);
(void)hns3vf_set_alive(hw, false);
(void)hns3vf_set_promisc_mode(hw, false, false, false);
hns3vf_disable_irq0(hw);
@@ -2202,6 +2212,10 @@ hns3vf_restore_conf(struct hns3_adapter *hns)
if (ret)
goto err_vlan_table;
+ ret = hns3_restore_gro_conf(hw);
+ if (ret)
+ goto err_vlan_table;
+
if (hw->adapter_state == HNS3_NIC_STARTED) {
ret = hns3vf_do_start(hns, false);
if (ret)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index db07fc459..c332b8703 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1571,6 +1571,7 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
uint32_t bd_base_info;
uint32_t cksum_err;
uint32_t l234_info;
+ uint32_t gro_size;
uint32_t ol_info;
uint64_t dma_addr;
uint16_t data_len;
@@ -1717,6 +1718,13 @@ hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
}
rxm->next = NULL;
+ gro_size = hns3_get_field(bd_base_info, HNS3_RXD_GRO_SIZE_M,
+ HNS3_RXD_GRO_SIZE_S);
+ if (gro_size != 0) {
+ first_seg->ol_flags |= PKT_RX_LRO;
+ first_seg->tso_segsz = gro_size;
+ }
+
ret = hns3_handle_bdinfo(rxq, first_seg, bd_base_info,
l234_info, &cksum_err);
if (unlikely(ret))
@@ -1902,6 +1910,43 @@ hns3_tso_proc_tunnel(struct hns3_desc *desc, uint64_t ol_flags,
return 0;
}
+int
+hns3_config_gro(struct hns3_hw *hw, bool en)
+{
+ struct hns3_cfg_gro_status_cmd *req;
+ struct hns3_cmd_desc desc;
+ int ret;
+
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GRO_GENERIC_CONFIG, false);
+ req = (struct hns3_cfg_gro_status_cmd *)desc.data;
+
+ req->gro_en = rte_cpu_to_le_16(en ? 1 : 0);
+
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret)
+ hns3_err(hw, "%s hardware GRO failed, ret = %d",
+ en ? "enable" : "disable", ret);
+
+ return ret;
+}
+
+int
+hns3_restore_gro_conf(struct hns3_hw *hw)
+{
+ uint64_t offloads;
+ bool gro_en;
+ int ret;
+
+ offloads = hw->data->dev_conf.rxmode.offloads;
+ gro_en = offloads & DEV_RX_OFFLOAD_TCP_LRO ? true : false;
+ ret = hns3_config_gro(hw, gro_en);
+ if (ret)
+ hns3_err(hw, "restore hardware GRO to %s failed, ret = %d",
+ gro_en ? "enabled" : "disabled", ret);
+
+ return ret;
+}
+
static inline bool
hns3_pkt_is_tso(struct rte_mbuf *m)
{
diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h
index ee4514290..1e80d2558 100644
--- a/drivers/net/hns3/hns3_rxtx.h
+++ b/drivers/net/hns3/hns3_rxtx.h
@@ -81,7 +81,7 @@
#define HNS3_RXD_TSIND_M (0x7 << HNS3_RXD_TSIND_S)
#define HNS3_RXD_LKBK_B 15
#define HNS3_RXD_GRO_SIZE_S 16
-#define HNS3_RXD_GRO_SIZE_M (0x3ff << HNS3_RXD_GRO_SIZE_S)
+#define HNS3_RXD_GRO_SIZE_M (0x3fff << HNS3_RXD_GRO_SIZE_S)
#define HNS3_TXD_L3T_S 0
#define HNS3_TXD_L3T_M (0x3 << HNS3_TXD_L3T_S)
@@ -384,5 +384,7 @@ void hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id,
uint16_t rl_value);
int hns3_set_fake_rx_or_tx_queues(struct rte_eth_dev *dev, uint16_t nb_rx_q,
uint16_t nb_tx_q);
+int hns3_config_gro(struct hns3_hw *hw, bool en);
+int hns3_restore_gro_conf(struct hns3_hw *hw);
#endif /* _HNS3_RXTX_H_ */
--
2.27.0
More information about the stable
mailing list