Skip to content

Commit

Permalink
Merge branch 'net-hns3-updates-for-next'
Browse files Browse the repository at this point in the history
Huazhong Tan says:

====================
net: hns3: updates for -next

There are several updates relating to the interrupt coalesce for
the HNS3 ethernet driver.

   based on the frame quantity).
   a fixed value in code.
   based on the gap time).
   its new usage.

change log:
V4 - remove #5~#10 from this series, which needs more discussion.
V3 - fix a typo error in #1 reported by Jakub Kicinski.
     rewrite #9 commit log.
     remove #11 from this series.
V2 - reorder #2 & #3 to fix compiler error.
     fix some checkpatch warnings in #10 & #11.

previous version:
V3: https://patchwork.ozlabs.org/project/netdev/cover/1605151998-12633-1-git-send-email-tanhuazhong@huawei.com/
V2: https://patchwork.ozlabs.org/project/netdev/cover/1604892159-19990-1-git-send-email-tanhuazhong@huawei.com/
V1: https://patchwork.ozlabs.org/project/netdev/cover/1604730681-32559-1-git-send-email-tanhuazhong@huawei.com/
====================

Link: https://lore.kernel.org/r/1605514854-11205-1-git-send-email-tanhuazhong@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Nov 17, 2020
2 parents 0676a4e + de25bcc commit fccf111
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 37 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/hisilicon/hns3/hnae3.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ struct hnae3_dev_specs {
u16 rss_ind_tbl_size;
u16 rss_key_size;
u16 int_ql_max; /* max value of interrupt coalesce based on INT_QL */
u16 max_int_gl; /* max value of interrupt coalesce based on INT_GL */
u8 max_non_tso_bd_num; /* max BD number of one non-TSO packet */
};

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ static void hns3_dbg_dev_specs(struct hnae3_handle *h)
dev_info(priv->dev, "Desc num per RX queue: %u\n", kinfo->num_rx_desc);
dev_info(priv->dev, "Total number of enabled TCs: %u\n", kinfo->num_tc);
dev_info(priv->dev, "MAX INT QL: %u\n", dev_specs->int_ql_max);
dev_info(priv->dev, "MAX INT GL: %u\n", dev_specs->max_int_gl);
}

static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
Expand Down
99 changes: 75 additions & 24 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
* GL and RL(Rate Limiter) are 2 ways to acheive interrupt coalescing
*/

if (rl_reg > 0 && !tqp_vector->tx_group.coal.gl_adapt_enable &&
!tqp_vector->rx_group.coal.gl_adapt_enable)
if (rl_reg > 0 && !tqp_vector->tx_group.coal.adapt_enable &&
!tqp_vector->rx_group.coal.adapt_enable)
/* According to the hardware, the range of rl_reg is
* 0-59 and the unit is 4.
*/
Expand All @@ -224,48 +224,99 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
void hns3_set_vector_coalesce_rx_gl(struct hns3_enet_tqp_vector *tqp_vector,
u32 gl_value)
{
u32 rx_gl_reg = hns3_gl_usec_to_reg(gl_value);
u32 new_val;

writel(rx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL0_OFFSET);
if (tqp_vector->rx_group.coal.unit_1us)
new_val = gl_value | HNS3_INT_GL_1US;
else
new_val = hns3_gl_usec_to_reg(gl_value);

writel(new_val, tqp_vector->mask_addr + HNS3_VECTOR_GL0_OFFSET);
}

void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
u32 gl_value)
{
u32 tx_gl_reg = hns3_gl_usec_to_reg(gl_value);
u32 new_val;

if (tqp_vector->tx_group.coal.unit_1us)
new_val = gl_value | HNS3_INT_GL_1US;
else
new_val = hns3_gl_usec_to_reg(gl_value);

writel(new_val, tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET);
}

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);
}

writel(tx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL1_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_gl_rl_init(struct hns3_enet_tqp_vector *tqp_vector,
struct hns3_nic_priv *priv)
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->adapt_enable = 1;
rx_coal->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;

/* device version above V3(include V3), GL can configure 1us
* unit, so uses 1us unit.
*/
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
tx_coal->unit_1us = 1;
rx_coal->unit_1us = 1;
}

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)
Expand Down Expand Up @@ -3333,14 +3384,14 @@ static void hns3_update_new_int_gl(struct hns3_enet_tqp_vector *tqp_vector)
tqp_vector->last_jiffies + msecs_to_jiffies(1000)))
return;

if (rx_group->coal.gl_adapt_enable) {
if (rx_group->coal.adapt_enable) {
rx_update = hns3_get_new_int_gl(rx_group);
if (rx_update)
hns3_set_vector_coalesce_rx_gl(tqp_vector,
rx_group->coal.int_gl);
}

if (tx_group->coal.gl_adapt_enable) {
if (tx_group->coal.adapt_enable) {
tx_update = hns3_get_new_int_gl(tx_group);
if (tx_update)
hns3_set_vector_coalesce_tx_gl(tqp_vector,
Expand Down Expand Up @@ -3536,7 +3587,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;
}

Expand Down Expand Up @@ -3632,7 +3683,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:
Expand Down
17 changes: 15 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -418,18 +420,25 @@ enum hns3_flow_level_range {
HNS3_FLOW_ULTRA = 3,
};

#define HNS3_INT_GL_MAX 0x1FE0
#define HNS3_INT_GL_50K 0x0014
#define HNS3_INT_GL_20K 0x0032
#define HNS3_INT_GL_18K 0x0036
#define HNS3_INT_GL_8K 0x007C

#define HNS3_INT_GL_1US BIT(31)

#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 adapt_enable:1;
u8 ql_enable:1;
u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
};

Expand Down Expand Up @@ -595,6 +604,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);
Expand Down
71 changes: 60 additions & 11 deletions drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,16 +1105,19 @@ static int hns3_get_coalesce_per_queue(struct net_device *netdev, u32 queue,
rx_vector = priv->ring[queue_num + queue].tqp_vector;

cmd->use_adaptive_tx_coalesce =
tx_vector->tx_group.coal.gl_adapt_enable;
tx_vector->tx_group.coal.adapt_enable;
cmd->use_adaptive_rx_coalesce =
rx_vector->rx_group.coal.gl_adapt_enable;
rx_vector->rx_group.coal.adapt_enable;

cmd->tx_coalesce_usecs = tx_vector->tx_group.coal.int_gl;
cmd->rx_coalesce_usecs = rx_vector->rx_group.coal.int_gl;

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;
}

Expand All @@ -1127,22 +1130,30 @@ static int hns3_get_coalesce(struct net_device *netdev,
static int hns3_check_gl_coalesce_para(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);
u32 rx_gl, tx_gl;

if (cmd->rx_coalesce_usecs > HNS3_INT_GL_MAX) {
if (cmd->rx_coalesce_usecs > ae_dev->dev_specs.max_int_gl) {
netdev_err(netdev,
"Invalid rx-usecs value, rx-usecs range is 0-%d\n",
HNS3_INT_GL_MAX);
"invalid rx-usecs value, rx-usecs range is 0-%u\n",
ae_dev->dev_specs.max_int_gl);
return -EINVAL;
}

if (cmd->tx_coalesce_usecs > HNS3_INT_GL_MAX) {
if (cmd->tx_coalesce_usecs > ae_dev->dev_specs.max_int_gl) {
netdev_err(netdev,
"Invalid tx-usecs value, tx-usecs range is 0-%d\n",
HNS3_INT_GL_MAX);
"invalid tx-usecs value, tx-usecs range is 0-%u\n",
ae_dev->dev_specs.max_int_gl);
return -EINVAL;
}

/* device version above V3(include V3), GL uses 1us unit,
* so the round down is not needed.
*/
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
return 0;

rx_gl = hns3_gl_round_down(cmd->rx_coalesce_usecs);
if (rx_gl != cmd->rx_coalesce_usecs) {
netdev_info(netdev,
Expand Down Expand Up @@ -1188,6 +1199,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)
{
Expand All @@ -1207,6 +1241,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,
Expand All @@ -1230,21 +1268,31 @@ static void hns3_set_coalesce_per_queue(struct net_device *netdev,
tx_vector = priv->ring[queue].tqp_vector;
rx_vector = priv->ring[queue_num + queue].tqp_vector;

tx_vector->tx_group.coal.gl_adapt_enable =
tx_vector->tx_group.coal.adapt_enable =
cmd->use_adaptive_tx_coalesce;
rx_vector->rx_group.coal.gl_adapt_enable =
rx_vector->rx_group.coal.adapt_enable =
cmd->use_adaptive_rx_coalesce;

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,
rx_vector->rx_group.coal.int_gl);

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,
Expand Down Expand Up @@ -1471,7 +1519,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,
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,14 @@ struct hclge_dev_specs_0_cmd {
__le32 max_tm_rate;
};

#define HCLGE_DEF_MAX_INT_GL 0x1FE0U

struct hclge_dev_specs_1_cmd {
__le32 rsv0;
__le16 max_int_gl;
u8 rsv1[18];
};

int hclge_cmd_init(struct hclge_dev *hdev);
static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value)
{
Expand Down
Loading

0 comments on commit fccf111

Please sign in to comment.