298 lines
11 KiB
Diff
298 lines
11 KiB
Diff
From 70a8b68f854337fc619fdfd150a037b3352563ee Mon Sep 17 00:00:00 2001
|
|
From: Huazhong Tan <tanhuazhong@huawei.com>
|
|
Date: Wed, 14 Jul 2021 20:55:24 +0800
|
|
Subject: [PATCH 069/283] net: hns3: add support for configuring interrupt
|
|
quantity limiting
|
|
|
|
mainline inclusion
|
|
from mainline-v5.11-rc1
|
|
commit 91bfae25eedd981b384339c7b12bef9eeaba0f34
|
|
category: feature
|
|
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8EMQV
|
|
CVE: NA
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=91bfae25eedd981b384339c7b12bef9eeaba0f34
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
QL(quantity limiting) means that hardware supports the interrupt
|
|
coalesce based on the frame quantity. QL can be configured when
|
|
int_ql_max in device's specification is non-zero, so add support
|
|
to configure it. Also, rename two coalesce init function to fit
|
|
their purpose.
|
|
|
|
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>
|
|
---
|
|
.../net/ethernet/hisilicon/hns3/hns3_enet.c | 65 ++++++++++++++-----
|
|
.../net/ethernet/hisilicon/hns3/hns3_enet.h | 13 +++-
|
|
.../ethernet/hisilicon/hns3/hns3_ethtool.c | 43 +++++++++++-
|
|
.../hisilicon/hns3/hns3pf/hclge_main.c | 1 +
|
|
.../hisilicon/hns3/hns3vf/hclgevf_main.c | 1 +
|
|
5 files changed, 105 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
index b78f2fe7f39c..dcf65dce1240 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
|
|
@@ -239,35 +239,68 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
|
|
writel(tx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET);
|
|
}
|
|
|
|
-static void hns3_vector_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
|
|
- struct hns3_nic_priv *priv)
|
|
+void hns3_set_vector_coalesce_tx_ql(struct hns3_enet_tqp_vector *tqp_vector,
|
|
+ u32 ql_value)
|
|
{
|
|
+ writel(ql_value, tqp_vector->mask_addr + HNS3_VECTOR_TX_QL_OFFSET);
|
|
+}
|
|
+
|
|
+void hns3_set_vector_coalesce_rx_ql(struct hns3_enet_tqp_vector *tqp_vector,
|
|
+ u32 ql_value)
|
|
+{
|
|
+ writel(ql_value, tqp_vector->mask_addr + HNS3_VECTOR_RX_QL_OFFSET);
|
|
+}
|
|
+
|
|
+static void hns3_vector_coalesce_init(struct hns3_enet_tqp_vector *tqp_vector,
|
|
+ struct hns3_nic_priv *priv)
|
|
+{
|
|
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
|
|
+ struct hns3_enet_coalesce *tx_coal = &tqp_vector->tx_group.coal;
|
|
+ struct hns3_enet_coalesce *rx_coal = &tqp_vector->rx_group.coal;
|
|
+
|
|
/* initialize the configuration for interrupt coalescing.
|
|
* 1. GL (Interrupt Gap Limiter)
|
|
* 2. RL (Interrupt Rate Limiter)
|
|
+ * 3. QL (Interrupt Quantity Limiter)
|
|
*
|
|
* Default: enable interrupt coalescing self-adaptive and GL
|
|
*/
|
|
- tqp_vector->tx_group.coal.gl_adapt_enable = 1;
|
|
- tqp_vector->rx_group.coal.gl_adapt_enable = 1;
|
|
+ tx_coal->gl_adapt_enable = 1;
|
|
+ rx_coal->gl_adapt_enable = 1;
|
|
+
|
|
+ tx_coal->int_gl = HNS3_INT_GL_50K;
|
|
+ rx_coal->int_gl = HNS3_INT_GL_50K;
|
|
|
|
- tqp_vector->tx_group.coal.int_gl = HNS3_INT_GL_50K;
|
|
- tqp_vector->rx_group.coal.int_gl = HNS3_INT_GL_50K;
|
|
+ rx_coal->flow_level = HNS3_FLOW_LOW;
|
|
+ tx_coal->flow_level = HNS3_FLOW_LOW;
|
|
|
|
- tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
|
|
- tqp_vector->tx_group.coal.flow_level = HNS3_FLOW_LOW;
|
|
+ if (ae_dev->dev_specs.int_ql_max) {
|
|
+ tx_coal->ql_enable = 1;
|
|
+ rx_coal->ql_enable = 1;
|
|
+ tx_coal->int_ql_max = ae_dev->dev_specs.int_ql_max;
|
|
+ rx_coal->int_ql_max = ae_dev->dev_specs.int_ql_max;
|
|
+ tx_coal->int_ql = HNS3_INT_QL_DEFAULT_CFG;
|
|
+ rx_coal->int_ql = HNS3_INT_QL_DEFAULT_CFG;
|
|
+ }
|
|
}
|
|
|
|
-static void hns3_vector_gl_rl_init_hw(struct hns3_enet_tqp_vector *tqp_vector,
|
|
- struct hns3_nic_priv *priv)
|
|
+static void
|
|
+hns3_vector_coalesce_init_hw(struct hns3_enet_tqp_vector *tqp_vector,
|
|
+ struct hns3_nic_priv *priv)
|
|
{
|
|
+ struct hns3_enet_coalesce *tx_coal = &tqp_vector->tx_group.coal;
|
|
+ struct hns3_enet_coalesce *rx_coal = &tqp_vector->rx_group.coal;
|
|
struct hnae3_handle *h = priv->ae_handle;
|
|
|
|
- hns3_set_vector_coalesce_tx_gl(tqp_vector,
|
|
- tqp_vector->tx_group.coal.int_gl);
|
|
- hns3_set_vector_coalesce_rx_gl(tqp_vector,
|
|
- tqp_vector->rx_group.coal.int_gl);
|
|
+ hns3_set_vector_coalesce_tx_gl(tqp_vector, tx_coal->int_gl);
|
|
+ hns3_set_vector_coalesce_rx_gl(tqp_vector, rx_coal->int_gl);
|
|
hns3_set_vector_coalesce_rl(tqp_vector, h->kinfo.int_rl_setting);
|
|
+
|
|
+ if (tx_coal->ql_enable)
|
|
+ hns3_set_vector_coalesce_tx_ql(tqp_vector, tx_coal->int_ql);
|
|
+
|
|
+ if (rx_coal->ql_enable)
|
|
+ hns3_set_vector_coalesce_rx_ql(tqp_vector, rx_coal->int_ql);
|
|
}
|
|
|
|
static int hns3_nic_set_real_num_queue(struct net_device *netdev)
|
|
@@ -3702,7 +3735,7 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
|
|
|
|
for (i = 0; i < priv->vector_num; i++) {
|
|
tqp_vector = &priv->tqp_vector[i];
|
|
- hns3_vector_gl_rl_init_hw(tqp_vector, priv);
|
|
+ hns3_vector_coalesce_init_hw(tqp_vector, priv);
|
|
tqp_vector->num_tqps = 0;
|
|
}
|
|
|
|
@@ -3798,7 +3831,7 @@ static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
|
|
tqp_vector->idx = i;
|
|
tqp_vector->mask_addr = vector[i].io_addr;
|
|
tqp_vector->vector_irq = vector[i].vector;
|
|
- hns3_vector_gl_rl_init(tqp_vector, priv);
|
|
+ hns3_vector_coalesce_init(tqp_vector, priv);
|
|
}
|
|
|
|
out:
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
index c337e4dbe2c6..0d9d46be1415 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
|
|
@@ -193,6 +193,8 @@ enum hns3_nic_state {
|
|
#define HNS3_VECTOR_GL2_OFFSET 0x300
|
|
#define HNS3_VECTOR_RL_OFFSET 0x900
|
|
#define HNS3_VECTOR_RL_EN_B 6
|
|
+#define HNS3_VECTOR_TX_QL_OFFSET 0xe00
|
|
+#define HNS3_VECTOR_RX_QL_OFFSET 0xf00
|
|
|
|
#define HNS3_RING_EN_B 0
|
|
|
|
@@ -447,9 +449,14 @@ enum hns3_flow_level_range {
|
|
#define HNS3_INT_RL_MAX 0x00EC
|
|
#define HNS3_INT_RL_ENABLE_MASK 0x40
|
|
|
|
+#define HNS3_INT_QL_DEFAULT_CFG 0x20
|
|
+
|
|
struct hns3_enet_coalesce {
|
|
u16 int_gl;
|
|
- u8 gl_adapt_enable;
|
|
+ u16 int_ql;
|
|
+ u16 int_ql_max;
|
|
+ u8 gl_adapt_enable:1;
|
|
+ u8 ql_enable:1;
|
|
enum hns3_flow_level_range flow_level;
|
|
};
|
|
|
|
@@ -621,6 +628,10 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
|
|
u32 gl_value);
|
|
void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
|
|
u32 rl_value);
|
|
+void hns3_set_vector_coalesce_rx_ql(struct hns3_enet_tqp_vector *tqp_vector,
|
|
+ u32 ql_value);
|
|
+void hns3_set_vector_coalesce_tx_ql(struct hns3_enet_tqp_vector *tqp_vector,
|
|
+ u32 ql_value);
|
|
|
|
void hns3_request_update_promisc_mode(struct hnae3_handle *handle);
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
index 3bad65d1a49d..7ed5f9a2ae38 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
|
|
@@ -1144,6 +1144,9 @@ static int hns3_get_coalesce_per_queue(struct net_device *netdev, u32 queue,
|
|
cmd->tx_coalesce_usecs_high = h->kinfo.int_rl_setting;
|
|
cmd->rx_coalesce_usecs_high = h->kinfo.int_rl_setting;
|
|
|
|
+ cmd->tx_max_coalesced_frames = tx_vector->tx_group.coal.int_ql;
|
|
+ cmd->rx_max_coalesced_frames = rx_vector->rx_group.coal.int_ql;
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1217,6 +1220,29 @@ static int hns3_check_rl_coalesce_para(struct net_device *netdev,
|
|
return 0;
|
|
}
|
|
|
|
+static int hns3_check_ql_coalesce_param(struct net_device *netdev,
|
|
+ struct ethtool_coalesce *cmd)
|
|
+{
|
|
+ struct hnae3_handle *handle = hns3_get_handle(netdev);
|
|
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
|
|
+
|
|
+ if ((cmd->tx_max_coalesced_frames || cmd->rx_max_coalesced_frames) &&
|
|
+ !ae_dev->dev_specs.int_ql_max) {
|
|
+ netdev_err(netdev, "coalesced frames is not supported\n");
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+
|
|
+ if (cmd->tx_max_coalesced_frames > ae_dev->dev_specs.int_ql_max ||
|
|
+ cmd->rx_max_coalesced_frames > ae_dev->dev_specs.int_ql_max) {
|
|
+ netdev_err(netdev,
|
|
+ "invalid coalesced_frames value, range is 0-%u\n",
|
|
+ ae_dev->dev_specs.int_ql_max);
|
|
+ return -ERANGE;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int hns3_check_coalesce_para(struct net_device *netdev,
|
|
struct ethtool_coalesce *cmd)
|
|
{
|
|
@@ -1236,6 +1262,10 @@ static int hns3_check_coalesce_para(struct net_device *netdev,
|
|
return ret;
|
|
}
|
|
|
|
+ ret = hns3_check_ql_coalesce_param(netdev, cmd);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
if (cmd->use_adaptive_tx_coalesce == 1 ||
|
|
cmd->use_adaptive_rx_coalesce == 1) {
|
|
netdev_info(netdev,
|
|
@@ -1267,6 +1297,9 @@ static void hns3_set_coalesce_per_queue(struct net_device *netdev,
|
|
tx_vector->tx_group.coal.int_gl = cmd->tx_coalesce_usecs;
|
|
rx_vector->rx_group.coal.int_gl = cmd->rx_coalesce_usecs;
|
|
|
|
+ tx_vector->tx_group.coal.int_ql = cmd->tx_max_coalesced_frames;
|
|
+ rx_vector->rx_group.coal.int_ql = cmd->rx_max_coalesced_frames;
|
|
+
|
|
hns3_set_vector_coalesce_tx_gl(tx_vector,
|
|
tx_vector->tx_group.coal.int_gl);
|
|
hns3_set_vector_coalesce_rx_gl(rx_vector,
|
|
@@ -1274,6 +1307,13 @@ static void hns3_set_coalesce_per_queue(struct net_device *netdev,
|
|
|
|
hns3_set_vector_coalesce_rl(tx_vector, h->kinfo.int_rl_setting);
|
|
hns3_set_vector_coalesce_rl(rx_vector, h->kinfo.int_rl_setting);
|
|
+
|
|
+ if (tx_vector->tx_group.coal.ql_enable)
|
|
+ hns3_set_vector_coalesce_tx_ql(tx_vector,
|
|
+ tx_vector->tx_group.coal.int_ql);
|
|
+ if (rx_vector->rx_group.coal.ql_enable)
|
|
+ hns3_set_vector_coalesce_rx_ql(rx_vector,
|
|
+ rx_vector->rx_group.coal.int_ql);
|
|
}
|
|
|
|
static int hns3_set_coalesce(struct net_device *netdev,
|
|
@@ -1501,7 +1541,8 @@ static int hns3_get_module_eeprom(struct net_device *netdev,
|
|
#define HNS3_ETHTOOL_COALESCE (ETHTOOL_COALESCE_USECS | \
|
|
ETHTOOL_COALESCE_USE_ADAPTIVE | \
|
|
ETHTOOL_COALESCE_RX_USECS_HIGH | \
|
|
- ETHTOOL_COALESCE_TX_USECS_HIGH)
|
|
+ ETHTOOL_COALESCE_TX_USECS_HIGH | \
|
|
+ ETHTOOL_COALESCE_MAX_FRAMES)
|
|
|
|
static const struct ethtool_ops hns3vf_ethtool_ops = {
|
|
.supported_coalesce_params = HNS3_ETHTOOL_COALESCE,
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
index bc70eb4fae64..3b4b1c8be8a3 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
|
|
@@ -1373,6 +1373,7 @@ static void hclge_parse_dev_specs(struct hclge_dev *hdev,
|
|
ae_dev->dev_specs.max_non_tso_bd_num = req0->max_non_tso_bd_num;
|
|
ae_dev->dev_specs.rss_ind_tbl_size =
|
|
le16_to_cpu(req0->rss_ind_tbl_size);
|
|
+ ae_dev->dev_specs.int_ql_max = le16_to_cpu(req0->int_ql_max);
|
|
ae_dev->dev_specs.rss_key_size = le16_to_cpu(req0->rss_key_size);
|
|
}
|
|
|
|
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
|
|
index ea1313a8e9da..b9a1b8032c5c 100644
|
|
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
|
|
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
|
|
@@ -3059,6 +3059,7 @@ static void hclgevf_parse_dev_specs(struct hclgevf_dev *hdev,
|
|
ae_dev->dev_specs.max_non_tso_bd_num = req0->max_non_tso_bd_num;
|
|
ae_dev->dev_specs.rss_ind_tbl_size =
|
|
le16_to_cpu(req0->rss_ind_tbl_size);
|
|
+ ae_dev->dev_specs.int_ql_max = le16_to_cpu(req0->int_ql_max);
|
|
ae_dev->dev_specs.rss_key_size = le16_to_cpu(req0->rss_key_size);
|
|
}
|
|
|
|
--
|
|
2.34.1
|
|
|