net: hns3: add support for configuring interrupt quantity limiting
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>
This commit is contained in:
parent
0676a4ea28
commit
91bfae25ee
@ -237,35 +237,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;
|
||||
|
||||
tqp_vector->tx_group.coal.int_gl = HNS3_INT_GL_50K;
|
||||
tqp_vector->rx_group.coal.int_gl = HNS3_INT_GL_50K;
|
||||
tx_coal->int_gl = HNS3_INT_GL_50K;
|
||||
rx_coal->int_gl = HNS3_INT_GL_50K;
|
||||
|
||||
tqp_vector->rx_group.coal.flow_level = HNS3_FLOW_LOW;
|
||||
tqp_vector->tx_group.coal.flow_level = HNS3_FLOW_LOW;
|
||||
rx_coal->flow_level = HNS3_FLOW_LOW;
|
||||
tx_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)
|
||||
@ -3536,7 +3569,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;
|
||||
}
|
||||
|
||||
@ -3632,7 +3665,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:
|
||||
|
@ -181,6 +181,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
|
||||
|
||||
@ -427,9 +429,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;
|
||||
};
|
||||
|
||||
@ -595,6 +602,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_enable_vlan_filter(struct net_device *netdev, bool enable);
|
||||
void hns3_request_update_promisc_mode(struct hnae3_handle *handle);
|
||||
|
@ -1115,6 +1115,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;
|
||||
}
|
||||
|
||||
@ -1188,6 +1191,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)
|
||||
{
|
||||
@ -1207,6 +1233,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,
|
||||
@ -1238,6 +1268,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,
|
||||
@ -1245,6 +1278,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,
|
||||
@ -1471,7 +1511,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,
|
||||
|
@ -1379,6 +1379,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);
|
||||
ae_dev->dev_specs.max_tm_rate = le32_to_cpu(req0->max_tm_rate);
|
||||
}
|
||||
|
@ -3004,6 +3004,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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user