[PATCH V2 net] net: phy: fix save wrong speed and duplex problem if autoneg is on

2021-02-26 Thread Huazhong Tan
From: Guangbin Huang 

If phy uses generic driver and autoneg is on, enter command
"ethtool -s eth0 speed 50" will not change phy speed actually, but
command "ethtool eth0" shows speed is 50Mb/s because phydev->speed
has been set to 50 and no update later.

And duplex setting has same problem too.

However, if autoneg is on, phy only changes speed and duplex according to
phydev->advertising, but not phydev->speed and phydev->duplex. So in this
case, phydev->speed and phydev->duplex don't need to be set in function
phy_ethtool_ksettings_set() if autoneg is on.

Fixes: 51e2a3846eab ("PHY: Avoid unnecessary aneg restarts")
Signed-off-by: Guangbin Huang 
Signed-off-by: Huazhong Tan 
---
V1->V2: add a Fixes tag
---
 drivers/net/phy/phy.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 1be07e4..fc2e7cb 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -276,14 +276,16 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
 
phydev->autoneg = autoneg;
 
-   phydev->speed = speed;
+   if (autoneg == AUTONEG_DISABLE) {
+   phydev->speed = speed;
+   phydev->duplex = duplex;
+   }
 
linkmode_copy(phydev->advertising, advertising);
 
linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
 phydev->advertising, autoneg == AUTONEG_ENABLE);
 
-   phydev->duplex = duplex;
phydev->master_slave_set = cmd->base.master_slave_cfg;
phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
 
-- 
2.7.4



Re: [PATCH net] net: phy: fix save wrong speed and duplex problem if autoneg is on

2021-02-26 Thread Huazhong Tan



On 2021/2/27 8:53, Andrew Lunn wrote:

On Fri, Feb 26, 2021 at 03:44:42PM +0800, Huazhong Tan wrote:

From: Guangbin Huang 

If phy uses generic driver and autoneg is on, enter command
"ethtool -s eth0 speed 50" will not change phy speed actually, but
command "ethtool eth0" shows speed is 50Mb/s because phydev->speed
has been set to 50 and no update later.

And duplex setting has same problem too.

However, if autoneg is on, phy only changes speed and duplex according to
phydev->advertising, but not phydev->speed and phydev->duplex. So in this
case, phydev->speed and phydev->duplex don't need to be set in function
phy_ethtool_ksettings_set() if autoneg is on.

Signed-off-by: Guangbin Huang 
Signed-off-by: Huazhong Tan 

I'm not sure, but i think this happens after

commit 51e2a3846eab18711f4eb59cd0a4c33054e2980a
Author: Trent Piepho 
Date:   Wed Sep 24 10:55:46 2008 +

 PHY: Avoid unnecessary aneg restarts
 
 The PHY's aneg is configured and restarted whenever the link is brought up,

 e.g. when DHCP is started after the kernel has booted.  This can take the
 link down for several seconds while auto-negotiation is redone.
 
 If the advertised features haven't changed, then it shouldn't be necessary

 to bring down the link and start auto-negotiation over again.
 
 genphy_config_advert() is enhanced to return 0 when the advertised features

 haven't been changed and >0 when they have been.
 
 genphy_config_aneg() then uses this information to not call

 genphy_restart_aneg() if there has been no change.

Before then, i think autoneg was unconditionally restarted, and so the
speed would get overwritten when autoneg completed. After this patch,
since autoneg is not being changed when only speed is set, autoneg is
not triggered.

Andrew



Thanks.



.




Re: [PATCH net] net: phy: fix save wrong speed and duplex problem if autoneg is on

2021-02-26 Thread Huazhong Tan



On 2021/2/27 7:56, Jakub Kicinski wrote:

On Fri, 26 Feb 2021 15:44:42 +0800 Huazhong Tan wrote:

From: Guangbin Huang 

If phy uses generic driver and autoneg is on, enter command
"ethtool -s eth0 speed 50" will not change phy speed actually, but
command "ethtool eth0" shows speed is 50Mb/s because phydev->speed
has been set to 50 and no update later.

And duplex setting has same problem too.

However, if autoneg is on, phy only changes speed and duplex according to
phydev->advertising, but not phydev->speed and phydev->duplex. So in this
case, phydev->speed and phydev->duplex don't need to be set in function
phy_ethtool_ksettings_set() if autoneg is on.

Can we get a Fixes tag for this one? How far back does this behavior
date?

will add a fixes tag in V2, thanks.

.




[PATCH net] net: phy: fix save wrong speed and duplex problem if autoneg is on

2021-02-25 Thread Huazhong Tan
From: Guangbin Huang 

If phy uses generic driver and autoneg is on, enter command
"ethtool -s eth0 speed 50" will not change phy speed actually, but
command "ethtool eth0" shows speed is 50Mb/s because phydev->speed
has been set to 50 and no update later.

And duplex setting has same problem too.

However, if autoneg is on, phy only changes speed and duplex according to
phydev->advertising, but not phydev->speed and phydev->duplex. So in this
case, phydev->speed and phydev->duplex don't need to be set in function
phy_ethtool_ksettings_set() if autoneg is on.

Signed-off-by: Guangbin Huang 
Signed-off-by: Huazhong Tan 
---
 drivers/net/phy/phy.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 1be07e4..fc2e7cb 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -276,14 +276,16 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
 
phydev->autoneg = autoneg;
 
-   phydev->speed = speed;
+   if (autoneg == AUTONEG_DISABLE) {
+   phydev->speed = speed;
+   phydev->duplex = duplex;
+   }
 
linkmode_copy(phydev->advertising, advertising);
 
linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
 phydev->advertising, autoneg == AUTONEG_ENABLE);
 
-   phydev->duplex = duplex;
phydev->master_slave_set = cmd->base.master_slave_cfg;
phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
 
-- 
2.7.4



Re: [PATCH][next] net: hns3: fix expression that is currently always true

2020-12-14 Thread Huazhong Tan



On 2020/12/15 8:00, Colin King wrote:

From: Colin Ian King

The ||  condition in hdev->fd_active_type != HCLGE_FD_ARFS_ACTIVE ||
hdev->fd_active_type != HCLGE_FD_RULE_NONE will always be true because
hdev->fd_active_type cannot be equal to two different values at the same
time. The expression is always true which is not correct. Fix this by
replacing || with && to correct the logic in the expression.

Addresses-Coverity: ("Constant expression result")
Fixes: 0205ec041ec6 ("net: hns3: add support for hw tc offload of tc flower")
Signed-off-by: Colin Ian King


Reviewed-by: Huazhong Tan 

Thanks.





[PATCH net-next 1/7] net: hns3: refine the struct hane3_tc_info

2020-12-09 Thread Huazhong Tan
From: Jian Shen 

Currently, there are multiple members related to tc information
in struct hnae3_knic_private_info. Merge them into a new struct
hnae3_tc_info.

Signed-off-by: Jian Shen 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h| 17 
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  3 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 33 +++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c |  2 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  4 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |  2 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 49 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 21 +-
 8 files changed, 64 insertions(+), 67 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 1a09b1f..0cb80ef 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -659,15 +659,16 @@ struct hnae3_ae_algo {
 #define HNAE3_INT_NAME_LEN32
 #define HNAE3_ITR_COUNTDOWN_START 100
 
+#define HNAE3_MAX_TC   8
+#define HNAE3_MAX_USER_PRIO8
 struct hnae3_tc_info {
-   u16 tqp_offset; /* TQP offset from base TQP */
-   u16 tqp_count;  /* Total TQPs */
-   u8  tc; /* TC index */
-   boolenable; /* If this TC is enable or not */
+   u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */
+   u16 tqp_count[HNAE3_MAX_TC];
+   u16 tqp_offset[HNAE3_MAX_TC];
+   unsigned long tc_en; /* bitmap of TC enabled */
+   u8 num_tc; /* Total number of enabled TCs */
 };
 
-#define HNAE3_MAX_TC   8
-#define HNAE3_MAX_USER_PRIO8
 struct hnae3_knic_private_info {
struct net_device *netdev; /* Set by KNIC client when init instance */
u16 rss_size;  /* Allocated RSS queues */
@@ -676,9 +677,7 @@ struct hnae3_knic_private_info {
u16 num_tx_desc;
u16 num_rx_desc;
 
-   u8 num_tc; /* Total number of enabled TCs */
-   u8 prio_tc[HNAE3_MAX_USER_PRIO];  /* TC indexed by prio */
-   struct hnae3_tc_info tc_info[HNAE3_MAX_TC]; /* Idx of array is HW TC */
+   struct hnae3_tc_info tc_info;
 
u16 num_tqps; /* total number of TQPs in this handle */
struct hnae3_queue **tqp;  /* array base of all TQPs in this instance */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index cb26742..9d4e9c0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -385,7 +385,8 @@ static void hns3_dbg_dev_specs(struct hnae3_handle *h)
dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len);
dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc);
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, "Total number of enabled TCs: %u\n",
+kinfo->tc_info.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);
 }
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 4c2fb86..36e74ad 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -323,13 +323,14 @@ static int hns3_nic_set_real_num_queue(struct net_device 
*netdev)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo = >kinfo;
-   unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
+   struct hnae3_tc_info *tc_info = >tc_info;
+   unsigned int queue_size = kinfo->rss_size * tc_info->num_tc;
int i, ret;
 
-   if (kinfo->num_tc <= 1) {
+   if (tc_info->num_tc <= 1) {
netdev_reset_tc(netdev);
} else {
-   ret = netdev_set_num_tc(netdev, kinfo->num_tc);
+   ret = netdev_set_num_tc(netdev, tc_info->num_tc);
if (ret) {
netdev_err(netdev,
   "netdev_set_num_tc fail, ret=%d!\n", ret);
@@ -337,13 +338,11 @@ static int hns3_nic_set_real_num_queue(struct net_device 
*netdev)
}
 
for (i = 0; i < HNAE3_MAX_TC; i++) {
-   if (!kinfo->tc_info[i].enable)
+   if (!test_bit(i, _info->tc_en))
continue;
 
- 

[PATCH net-next 0/7] net: hns3: updates for -next

2020-12-09 Thread Huazhong Tan
This patchset adds support for tc mqprio offload, hw tc
offload of tc flower, and adpation for max rss size changes.

Guojia Liao (3):
  net: hns3: add support for max 512 rss size
  net: hns3: adjust rss indirection table configure command
  net: hns3: adjust rss tc mode configure command

Jian Shen (4):
  net: hns3: refine the struct hane3_tc_info
  net: hns3: add support for tc mqprio offload
  net: hns3: add support for forwarding packet to queues of specified TC
when flow director rule hit
  net: hns3: add support for hw tc offload of tc flower

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  34 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |   3 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 112 -
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  16 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 126 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c |   2 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 466 ++---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  28 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |   2 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  98 +++--
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  21 +-
 12 files changed, 759 insertions(+), 151 deletions(-)

-- 
2.7.4



[PATCH net-next 3/7] net: hns3: add support for forwarding packet to queues of specified TC when flow director rule hit

2020-12-09 Thread Huazhong Tan
From: Jian Shen 

For some new device, it supports forwarding packet to queues
of specified TC when flow director rule hit. So extend the
command handle to support it.

Signed-off-by: Jian Shen 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c  |  2 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h  |  3 +++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 21 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h |  6 +-
 4 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 85986c7..b728be4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -359,6 +359,8 @@ static void hclge_parse_capability(struct hclge_dev *hdev,
set_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps);
if (hnae3_get_bit(caps, HCLGE_CAP_UDP_TUNNEL_CSUM_B))
set_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, ae_dev->caps);
+   if (hnae3_get_bit(caps, HCLGE_CAP_FD_FORWARD_TC_B))
+   set_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_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 52a6f9b..df5417d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -1051,6 +1051,9 @@ struct hclge_fd_tcam_config_3_cmd {
 #define HCLGE_FD_AD_WR_RULE_ID_B   0
 #define HCLGE_FD_AD_RULE_ID_S  1
 #define HCLGE_FD_AD_RULE_ID_M  GENMASK(13, 1)
+#define HCLGE_FD_AD_TC_OVRD_B  16
+#define HCLGE_FD_AD_TC_SIZE_S  17
+#define HCLGE_FD_AD_TC_SIZE_M  GENMASK(20, 17)
 
 struct hclge_fd_ad_config_cmd {
u8 stage;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 366920b..0b6102e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -5099,6 +5099,7 @@ static int hclge_fd_tcam_config(struct hclge_dev *hdev, 
u8 stage, bool sel_x,
 static int hclge_fd_ad_config(struct hclge_dev *hdev, u8 stage, int loc,
  struct hclge_fd_ad_data *action)
 {
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
struct hclge_fd_ad_config_cmd *req;
struct hclge_desc desc;
u64 ad_data = 0;
@@ -5114,6 +5115,12 @@ static int hclge_fd_ad_config(struct hclge_dev *hdev, u8 
stage, int loc,
  action->write_rule_id_to_bd);
hnae3_set_field(ad_data, HCLGE_FD_AD_RULE_ID_M, HCLGE_FD_AD_RULE_ID_S,
action->rule_id);
+   if (test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps)) {
+   hnae3_set_bit(ad_data, HCLGE_FD_AD_TC_OVRD_B,
+ action->override_tc);
+   hnae3_set_field(ad_data, HCLGE_FD_AD_TC_SIZE_M,
+   HCLGE_FD_AD_TC_SIZE_S, (u32)action->tc_size);
+   }
ad_data <<= 32;
hnae3_set_bit(ad_data, HCLGE_FD_AD_DROP_B, action->drop_packet);
hnae3_set_bit(ad_data, HCLGE_FD_AD_DIRECT_QID_B,
@@ -5357,16 +5364,22 @@ static int hclge_config_key(struct hclge_dev *hdev, u8 
stage,
 static int hclge_config_action(struct hclge_dev *hdev, u8 stage,
   struct hclge_fd_rule *rule)
 {
+   struct hclge_vport *vport = hdev->vport;
+   struct hnae3_knic_private_info *kinfo = >nic.kinfo;
struct hclge_fd_ad_data ad_data;
 
+   memset(_data, 0, sizeof(struct hclge_fd_ad_data));
ad_data.ad_id = rule->location;
 
if (rule->action == HCLGE_FD_ACTION_DROP_PACKET) {
ad_data.drop_packet = true;
-   ad_data.forward_to_direct_queue = false;
-   ad_data.queue_id = 0;
+   } else if (rule->action == HCLGE_FD_ACTION_SELECT_TC) {
+   ad_data.override_tc = true;
+   ad_data.queue_id =
+   kinfo->tc_info.tqp_offset[rule->tc];
+   ad_data.tc_size =
+   ilog2(kinfo->tc_info.tqp_count[rule->tc]);
} else {
-   ad_data.drop_packet = false;
ad_data.forward_to_direct_queue = true;
ad_data.queue_id = rule->queue_id;
}
@@ -5937,7 +5950,7 @@ static int hclge_add_fd_entry(struct hnae3_handle *handle,
return -EINVAL;
}
 
-   action = HCLGE_FD_ACTION_ACCEPT_PACKET;
+   action = HCLGE_FD_ACTION_SELECT_QUEUE;
q_index = ring;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/dri

[PATCH net-next 5/7] net: hns3: add support for max 512 rss size

2020-12-09 Thread Huazhong Tan
From: Guojia Liao 

Currently, the driver gets the max rss size from configuration
file when initialization. Both the PF and VF share the same
max rss size, and no more than 128.

For DEVICE_VERSION_V3, the max rss size for PF can be up to
512, so there is a new field in configuration file to store it,
the old filed is used for VF.

To be compatible with boards using old configure file, the PF
will use the old filed if the one is zero.

For the rss size may be larger than 256, so the type of
rss_indirection_tbl of struct hclge_vport should be changed to
u16 as well.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  2 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c |  4 +--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 36 --
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  8 +++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  5 ++-
 5 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index df5417d..f5a620c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -518,6 +518,8 @@ struct hclge_pf_res_cmd {
 #define HCLGE_CFG_SPEED_ABILITY_EXT_M  GENMASK(15, 10)
 #define HCLGE_CFG_UMV_TBL_SPACE_S  16
 #define HCLGE_CFG_UMV_TBL_SPACE_M  GENMASK(31, 16)
+#define HCLGE_CFG_PF_RSS_SIZE_S0
+#define HCLGE_CFG_PF_RSS_SIZE_MGENMASK(3, 0)
 
 #define HCLGE_CFG_CMD_CNT  4
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index a7f4c6a..e08d11b8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -421,10 +421,10 @@ static int hclge_mqprio_qopt_check(struct hclge_dev *hdev,
return -EINVAL;
}
 
-   if (mqprio_qopt->qopt.count[i] > hdev->rss_size_max) {
+   if (mqprio_qopt->qopt.count[i] > hdev->pf_rss_size_max) {
dev_err(>pdev->dev,
"qopt queue count should be no more than %u\n",
-   hdev->rss_size_max);
+   hdev->pf_rss_size_max);
return -EINVAL;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 455ee6c..f361226 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1285,9 +1285,9 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct 
hclge_desc *desc)
cfg->default_speed = hnae3_get_field(__le32_to_cpu(req->param[3]),
 HCLGE_CFG_DEFAULT_SPEED_M,
 HCLGE_CFG_DEFAULT_SPEED_S);
-   cfg->rss_size_max = hnae3_get_field(__le32_to_cpu(req->param[3]),
-   HCLGE_CFG_RSS_SIZE_M,
-   HCLGE_CFG_RSS_SIZE_S);
+   cfg->vf_rss_size_max = hnae3_get_field(__le32_to_cpu(req->param[3]),
+  HCLGE_CFG_RSS_SIZE_M,
+  HCLGE_CFG_RSS_SIZE_S);
 
for (i = 0; i < ETH_ALEN; i++)
cfg->mac_addr[i] = (mac_addr_tmp >> (8 * i)) & 0xff;
@@ -1308,6 +1308,21 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, 
struct hclge_desc *desc)
 HCLGE_CFG_UMV_TBL_SPACE_S);
if (!cfg->umv_space)
cfg->umv_space = HCLGE_DEFAULT_UMV_SPACE_PER_PF;
+
+   cfg->pf_rss_size_max = hnae3_get_field(__le32_to_cpu(req->param[2]),
+  HCLGE_CFG_PF_RSS_SIZE_M,
+  HCLGE_CFG_PF_RSS_SIZE_S);
+
+   /* HCLGE_CFG_PF_RSS_SIZE_M is the PF max rss size, which is a
+* power of 2, instead of reading out directly. This would
+* be more flexible for future changes and expansions.
+* When VF max  rss size field is HCLGE_CFG_RSS_SIZE_S,
+* it does not make sense if PF's field is 0. In this case, PF and VF
+* has the same max rss size filed: HCLGE_CFG_RSS_SIZE_S.
+*/
+   cfg->pf_rss_size_max = cfg->pf_rss_size_max ?
+  1U << cfg->pf_rss_size_max :
+  cfg->vf_rss_size_max;
 }
 
 /* hclge_get_cfg: query the static parameter from flash
@@ -1469,7 +1484,8 @@ static int hclge_configure(struct hclge_dev *hdev)
 
hdev->num_vmdq_vport = cfg.

[PATCH net-next 6/7] net: hns3: adjust rss indirection table configure command

2020-12-09 Thread Huazhong Tan
From: Guojia Liao 

For the max rss size of PF may be up to 512, so adjust the
command of configuring rss indirection table to support
queue id larger than 255. The width of queue id is extended
from 8 bits to 10 bits. The high 2 bits are stored in filed
rss_qid_h when the queue id is larger than 255.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h   |  7 +--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c  | 20 ++--
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index f5a620c..a6c306b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -560,12 +560,15 @@ struct hclge_rss_input_tuple_cmd {
 };
 
 #define HCLGE_RSS_CFG_TBL_SIZE 16
+#define HCLGE_RSS_CFG_TBL_SIZE_H   4
+#define HCLGE_RSS_CFG_TBL_BW_H 2U
+#define HCLGE_RSS_CFG_TBL_BW_L 8U
 
 struct hclge_rss_indirection_table_cmd {
__le16 start_table_index;
__le16 rss_set_bitmap;
-   u8 rsv[4];
-   u8 rss_result[HCLGE_RSS_CFG_TBL_SIZE];
+   u8 rss_qid_h[HCLGE_RSS_CFG_TBL_SIZE_H];
+   u8 rss_qid_l[HCLGE_RSS_CFG_TBL_SIZE];
 };
 
 #define HCLGE_RSS_TC_OFFSET_S  0
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index f361226..5de45a9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -4282,8 +4282,12 @@ static int hclge_set_rss_indir_table(struct hclge_dev 
*hdev, const u16 *indir)
 {
struct hclge_rss_indirection_table_cmd *req;
struct hclge_desc desc;
-   int i, j;
+   u8 rss_msb_oft;
+   u8 rss_msb_val;
int ret;
+   u16 qid;
+   int i;
+   u32 j;
 
req = (struct hclge_rss_indirection_table_cmd *)desc.data;
 
@@ -4294,11 +4298,15 @@ static int hclge_set_rss_indir_table(struct hclge_dev 
*hdev, const u16 *indir)
req->start_table_index =
cpu_to_le16(i * HCLGE_RSS_CFG_TBL_SIZE);
req->rss_set_bitmap = cpu_to_le16(HCLGE_RSS_SET_BITMAP_MSK);
-
-   for (j = 0; j < HCLGE_RSS_CFG_TBL_SIZE; j++)
-   req->rss_result[j] =
-   indir[i * HCLGE_RSS_CFG_TBL_SIZE + j];
-
+   for (j = 0; j < HCLGE_RSS_CFG_TBL_SIZE; j++) {
+   qid = indir[i * HCLGE_RSS_CFG_TBL_SIZE + j];
+   req->rss_qid_l[j] = qid & 0xff;
+   rss_msb_oft =
+   j * HCLGE_RSS_CFG_TBL_BW_H / BITS_PER_BYTE;
+   rss_msb_val = (qid >> HCLGE_RSS_CFG_TBL_BW_L & 0x1) <<
+   (j * HCLGE_RSS_CFG_TBL_BW_H % BITS_PER_BYTE);
+   req->rss_qid_h[rss_msb_oft] |= rss_msb_val;
+   }
ret = hclge_cmd_send(>hw, , 1);
if (ret) {
dev_err(>pdev->dev,
-- 
2.7.4



[PATCH net-next 7/7] net: hns3: adjust rss tc mode configure command

2020-12-09 Thread Huazhong Tan
From: Guojia Liao 

For the max rss size of PF may be up to 512, the max queue
number of single tc may be up to 512 too. For the total queue
numbers may be up to 1280, so the queue offset of each tc may
be more than 1024. So adjust the rss tc mode configuration
command, including extend tc size field from 10 bits to 11
bits, and extend tc size field from 3 bits to 4 bits.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h  | 4 +++-
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 ++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index a6c306b..edfadb5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -572,9 +572,11 @@ struct hclge_rss_indirection_table_cmd {
 };
 
 #define HCLGE_RSS_TC_OFFSET_S  0
-#define HCLGE_RSS_TC_OFFSET_M  GENMASK(9, 0)
+#define HCLGE_RSS_TC_OFFSET_M  GENMASK(10, 0)
+#define HCLGE_RSS_TC_SIZE_MSB_B11
 #define HCLGE_RSS_TC_SIZE_S12
 #define HCLGE_RSS_TC_SIZE_MGENMASK(14, 12)
+#define HCLGE_RSS_TC_SIZE_MSB_OFFSET   3
 #define HCLGE_RSS_TC_VALID_B   15
 struct hclge_rss_tc_mode_cmd {
__le16 rss_tc_mode[HCLGE_MAX_TC_NUM];
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 5de45a9..7a16411 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -4335,6 +4335,8 @@ static int hclge_set_rss_tc_mode(struct hclge_dev *hdev, 
u16 *tc_valid,
hnae3_set_bit(mode, HCLGE_RSS_TC_VALID_B, (tc_valid[i] & 0x1));
hnae3_set_field(mode, HCLGE_RSS_TC_SIZE_M,
HCLGE_RSS_TC_SIZE_S, tc_size[i]);
+   hnae3_set_bit(mode, HCLGE_RSS_TC_SIZE_MSB_B,
+ tc_size[i] >> HCLGE_RSS_TC_SIZE_MSB_OFFSET & 0x1);
hnae3_set_field(mode, HCLGE_RSS_TC_OFFSET_M,
HCLGE_RSS_TC_OFFSET_S, tc_offset[i]);
 
-- 
2.7.4



[PATCH net-next 2/7] net: hns3: add support for tc mqprio offload

2020-12-09 Thread Huazhong Tan
From: Jian Shen 

Currently, the HNS3 driver only supports offload for tc number
and prio_tc. This patch adds support for other qopts, including
queues count and offset for each tc.

When enable tc mqprio offload, it's not allowed to change
queue numbers by ethtool. For hardware limitation, the queue
number of each tc should be power of 2.

For the queues is not assigned to each tc by average, so it's
should return vport->alloc_tqps for hclge_get_max_channels().

Signed-off-by: Jian Shen 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|   6 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  13 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 126 +++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  80 +++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  48 +++-
 5 files changed, 220 insertions(+), 53 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 0cb80ef..a7ff9c7 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -29,7 +29,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #define HNAE3_MOD_VERSION "1.0"
 
@@ -647,7 +649,8 @@ struct hnae3_dcb_ops {
u8   (*getdcbx)(struct hnae3_handle *);
u8   (*setdcbx)(struct hnae3_handle *, u8);
 
-   int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
+   int (*setup_tc)(struct hnae3_handle *handle,
+   struct tc_mqprio_qopt_offload *mqprio_qopt);
 };
 
 struct hnae3_ae_algo {
@@ -667,6 +670,7 @@ struct hnae3_tc_info {
u16 tqp_offset[HNAE3_MAX_TC];
unsigned long tc_en; /* bitmap of TC enabled */
u8 num_tc; /* Total number of enabled TCs */
+   bool mqprio_active;
 };
 
 struct hnae3_knic_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 36e74ad..d6dd4bc 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -324,10 +324,10 @@ static int hns3_nic_set_real_num_queue(struct net_device 
*netdev)
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo = >kinfo;
struct hnae3_tc_info *tc_info = >tc_info;
-   unsigned int queue_size = kinfo->rss_size * tc_info->num_tc;
+   unsigned int queue_size = kinfo->num_tqps;
int i, ret;
 
-   if (tc_info->num_tc <= 1) {
+   if (tc_info->num_tc <= 1 && !tc_info->mqprio_active) {
netdev_reset_tc(netdev);
} else {
ret = netdev_set_num_tc(netdev, tc_info->num_tc);
@@ -1793,7 +1793,6 @@ static void hns3_nic_get_stats64(struct net_device 
*netdev,
 static int hns3_setup_tc(struct net_device *netdev, void *type_data)
 {
struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
-   u8 *prio_tc = mqprio_qopt->qopt.prio_tc_map;
struct hnae3_knic_private_info *kinfo;
u8 tc = mqprio_qopt->qopt.num_tc;
u16 mode = mqprio_qopt->mode;
@@ -1816,7 +1815,7 @@ static int hns3_setup_tc(struct net_device *netdev, void 
*type_data)
netif_dbg(h, drv, netdev, "setup tc: num_tc=%u\n", tc);
 
return (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
-   kinfo->dcb_ops->setup_tc(h, tc ? tc : 1, prio_tc) : -EOPNOTSUPP;
+   kinfo->dcb_ops->setup_tc(h, mqprio_qopt) : -EOPNOTSUPP;
 }
 
 static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
@@ -4691,6 +4690,12 @@ int hns3_set_channels(struct net_device *netdev,
if (ch->rx_count || ch->tx_count)
return -EINVAL;
 
+   if (kinfo->tc_info.mqprio_active) {
+   dev_err(>dev,
+   "it's not allowed to set channels via ethtool when 
MQPRIO mode is on\n");
+   return -EINVAL;
+   }
+
if (new_tqp_num > hns3_get_max_available_channels(h) ||
new_tqp_num < 1) {
dev_err(>dev,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index f990f69..a7f4c6a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -397,32 +397,130 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
return 0;
 }
 
+static int hclge_mqprio_qopt_check(struct hclge_dev *hdev,
+  struct tc_mqprio_qopt_offload *mqprio_qopt)
+{
+   u16 queue_sum = 0;
+   int ret;
+   int i;
+
+   if (!mqprio_qopt->qopt.num_tc) {
+   mqprio_qopt->qopt.num_tc = 1;
+   return 0;
+   }
+
+   ret = hclge_dcb_common_validate(hdev

[PATCH net-next 4/7] net: hns3: add support for hw tc offload of tc flower

2020-12-09 Thread Huazhong Tan
From: Jian Shen 

Some new device supports forwarding packet to queues of specified
TC when flow director rule hit. So add support to configure flow
director rule by tc flower. To avoid rule conflict, add a new flow
director mode HCLGE_FD_TC_FLOWER_ACTIVE, and only one mode can be
active at the same time.

Signed-off-by: Jian Shen 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  11 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  70 -
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 313 -
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  16 +-
 4 files changed, 397 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index a7ff9c7..a7daf6d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -459,6 +459,12 @@ struct hnae3_ae_dev {
  *   Configure the default MAC for specified VF
  * get_module_eeprom
  *   Get the optical module eeprom info.
+ * add_cls_flower
+ *   Add clsflower rule
+ * del_cls_flower
+ *   Delete clsflower rule
+ * cls_flower_active
+ *   Check if any cls flower rule exist
  */
 struct hnae3_ae_ops {
int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
@@ -636,6 +642,11 @@ struct hnae3_ae_ops {
int (*get_module_eeprom)(struct hnae3_handle *handle, u32 offset,
 u32 len, u8 *data);
bool (*get_cmdq_stat)(struct hnae3_handle *handle);
+   int (*add_cls_flower)(struct hnae3_handle *handle,
+ struct flow_cls_offload *cls_flower, int tc);
+   int (*del_cls_flower)(struct hnae3_handle *handle,
+ struct flow_cls_offload *cls_flower);
+   bool (*cls_flower_active)(struct hnae3_handle *handle);
 };
 
 struct hnae3_dcb_ops {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index d6dd4bc..405e490 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1668,6 +1668,13 @@ static int hns3_nic_set_features(struct net_device 
*netdev,
h->ae_algo->ops->enable_fd(h, enable);
}
 
+   if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
+   h->ae_algo->ops->cls_flower_active(h)) {
+   netdev_err(netdev,
+  "there are offloaded TC filters active, cannot 
disable HW TC offload");
+   return -EINVAL;
+   }
+
netdev->features = features;
return 0;
 }
@@ -1818,13 +1825,67 @@ static int hns3_setup_tc(struct net_device *netdev, 
void *type_data)
kinfo->dcb_ops->setup_tc(h, mqprio_qopt) : -EOPNOTSUPP;
 }
 
+static int hns3_setup_tc_cls_flower(struct hns3_nic_priv *priv,
+   struct flow_cls_offload *flow)
+{
+   int tc = tc_classid_to_hwtc(priv->netdev, flow->classid);
+   struct hnae3_handle *h = hns3_get_handle(priv->netdev);
+
+   switch (flow->command) {
+   case FLOW_CLS_REPLACE:
+   if (h->ae_algo->ops->add_cls_flower)
+   return h->ae_algo->ops->add_cls_flower(h, flow, tc);
+   break;
+   case FLOW_CLS_DESTROY:
+   if (h->ae_algo->ops->del_cls_flower)
+   return h->ae_algo->ops->del_cls_flower(h, flow);
+   break;
+   default:
+   break;
+   }
+
+   return -EOPNOTSUPP;
+}
+
+static int hns3_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
+ void *cb_priv)
+{
+   struct hns3_nic_priv *priv = cb_priv;
+
+   if (!tc_cls_can_offload_and_chain0(priv->netdev, type_data))
+   return -EOPNOTSUPP;
+
+   switch (type) {
+   case TC_SETUP_CLSFLOWER:
+   return hns3_setup_tc_cls_flower(priv, type_data);
+   default:
+   return -EOPNOTSUPP;
+   }
+}
+
+static LIST_HEAD(hns3_block_cb_list);
+
 static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
 void *type_data)
 {
-   if (type != TC_SETUP_QDISC_MQPRIO)
+   struct hns3_nic_priv *priv = netdev_priv(dev);
+   int ret;
+
+   switch (type) {
+   case TC_SETUP_QDISC_MQPRIO:
+   ret = hns3_setup_tc(dev, type_data);
+   break;
+   case TC_SETUP_BLOCK:
+   ret = flow_block_cb_setup_simple(type_data,
+_block_cb_list,
+hns3_setup_tc_block_cb,
+priv, priv, true);
+   break;
+   default:
return -EOPNOTSUPP;
+   }
 
-   ret

[PATCH net] net: hns3: remove a misused pragma packed

2020-12-06 Thread Huazhong Tan
hclge_dbg_reg_info[] is defined as an array of packed structure
accidentally. However, this array contains pointers, which are
no longer aligned naturally, and cannot be relocated on PPC64.
Hence, when compile-testing this driver on PPC64 with
CONFIG_RELOCATABLE=y (e.g. PowerPC allyesconfig), there will be
some warnings.

Since each field in structure hclge_qos_pri_map_cmd and
hclge_dbg_bitmap_cmd is type u8, the pragma packed is unnecessary
for these two structures as well, so remove the pragma packed in
hclge_debugfs.h to fix this issue, and this increases
hclge_dbg_reg_info[] by 4 bytes per entry.

Fixes: a582b78dfc33 ("net: hns3: code optimization for debugfs related to "dump 
reg"")
Reported-by: Stephen Rothwell 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h
index a9066e6..ca2ab6c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h
@@ -35,8 +35,6 @@
 
 #define HCLGE_DBG_DFX_SSU_2_OFFSET 12
 
-#pragma pack(1)
-
 struct hclge_qos_pri_map_cmd {
u8 pri0_tc  : 4,
   pri1_tc  : 4;
@@ -85,8 +83,6 @@ struct hclge_dbg_reg_type_info {
struct hclge_dbg_reg_common_msg reg_msg;
 };
 
-#pragma pack()
-
 static const struct hclge_dbg_dfx_message hclge_dbg_bios_common_reg[] = {
{false, "Reserved"},
{true,  "BP_CPU_STATE"},
-- 
2.7.4



[PATCH V2 net-next 2/3] net: hns3: add priv flags support to switch limit promisc mode

2020-12-05 Thread Huazhong Tan
From: Jian Shen 

Currently, the tx unicast promisc is always enabled when promisc
mode on. If tx unicast promisc on, a function will receive all
unicast packet from other functions belong to the same port.
Add a ethtool private flag to control whether enable tx
unicast promisc. Then the function is able to filter the
unknown unicast packets from other function.

Signed-off-by: Jian Shen 
---
 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  8 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  3 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 86 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  8 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |  7 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  7 ++
 7 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h 
b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
index 1ffe8fa..fb5e884 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
@@ -110,6 +110,7 @@ struct hclge_vf_to_pf_msg {
u8 en_bc;
u8 en_uc;
u8 en_mc;
+   u8 en_limit_promisc;
};
struct {
u8 vector_id;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 78b4886..1a09b1f 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -719,6 +719,11 @@ struct hnae3_roce_private_info {
 #define HNAE3_UPE  (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
 #define HNAE3_MPE  (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
 
+enum hnae3_pflag {
+   HNAE3_PFLAG_LIMIT_PROMISC,
+   HNAE3_PFLAG_MAX
+};
+
 struct hnae3_handle {
struct hnae3_client *client;
struct pci_dev *pdev;
@@ -741,6 +746,9 @@ struct hnae3_handle {
 
/* Network interface message level enabled bits */
u32 msg_enable;
+
+   unsigned long supported_pflags;
+   unsigned long priv_flags;
 };
 
 #define hnae3_set_field(origin, mask, shift, val) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 1798c0a..69ae15b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4226,6 +4226,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
 
set_bit(HNS3_NIC_STATE_INITED, >state);
 
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+   set_bit(HNAE3_PFLAG_LIMIT_PROMISC, >supported_pflags);
+
if (netif_msg_drv(handle))
hns3_info_show(priv);
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 3cca3c1..e2fc443 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -18,6 +18,11 @@ struct hns3_sfp_type {
u8 ext_type;
 };
 
+struct hns3_pflag_desc {
+   char name[ETH_GSTRING_LEN];
+   void (*handler)(struct net_device *netdev, bool enable);
+};
+
 /* tqp related stats */
 #define HNS3_TQP_STAT(_string, _member){   \
.stats_string = _string,\
@@ -60,6 +65,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
 
+#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
+
 #define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
 
 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
@@ -395,6 +402,23 @@ static void hns3_self_test(struct net_device *ndev,
netif_dbg(h, drv, ndev, "self test end\n");
 }
 
+static void hns3_update_limit_promisc_mode(struct net_device *netdev,
+  bool enable)
+{
+   struct hnae3_handle *handle = hns3_get_handle(netdev);
+
+   if (enable)
+   set_bit(HNAE3_PFLAG_LIMIT_PROMISC, >priv_flags);
+   else
+   clear_bit(HNAE3_PFLAG_LIMIT_PROMISC, >priv_flags);
+
+   hns3_request_update_promisc_mode(handle);
+}
+
+static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
+   { "limit_promisc",  hns3_update_limit_promisc_mode }
+};
+
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -411,6 +435,9 @@ static int hns3_get_sset_count(struct net_device *netdev, 
int stringset)
case ETH_SS_TEST:
return ops->get_sset_count(h, stringset);
 
+   case ETH_SS_PRIV_FLAGS:
+   return HNAE3_PFLAG_MAX;
+
default:
return -EOPNOTSUPP;
}
@@ -464,6 +491,7 @@ static void 

[PATCH V2 net-next 3/3] net: hns3: refine the VLAN tag handle for port based VLAN

2020-12-05 Thread Huazhong Tan
From: Guojia Liao 

For DEVICE_VERSION_V2, the hardware only supports max two layer
VLAN tags, including port based tag inserted by hardware, tag in
tx buffer descriptor(get from skb->tci) and tag in packet.

For transmit packet:
If port based VLAN disabled, and vf driver gets a VLAN tag from
skb, the VLAN tag must be filled to the Outer_VLAN_TAG field
(tag near to DMAC) of tx buffer descriptor, otherwise it may
be inserted after the tag in packet.

If port based VLAN enabled, and vf driver gets a VLAN tag from
skb, the VLAN tag must be filled to the VLAN_TAG field (tag
far to DMAC) of tx buffer descriptor, otherwise it may be
conflicted with port based VLAN, and raise a hardware error.

For receive packet:
The hardware will strip the VLAN tags and fill them in the rx
buffer descriptor, no matter port based VLAN enable or not.
Because port based VLAN tag is useless for stack, so vf driver
needs to discard the port based VLAN tag get from rx buffer
descriptor when port based VLAN enabled.

So vf must know about the port based VLAN state.

For DEVICE_VERSION_V3, the hardware provides some new
configuration to improve it.

For transmit packet:
When enable tag shift mode, hardware will handle the VLAN tag
in outer_VLAN_TAG field as VLAN_TAG, so it won't conflict with
port based VLAN. And hardware also make sure the tag before
the tag in packet. So vf driver doesn't need to specify the tag
position according to the port based VLAN state anymore.

For receive packet:
When enable discard mode, hardware will strip and discard the
port based VLAN tag, so vf driver doesn't need to identify it
from rx buffer descriptor.

So modify the port based VLAN configuration, simplify the process
for vf handling the VLAN tag.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  8 +++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  3 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 46 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 13 +++---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 11 +-
 5 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 69ae15b..4c2fb86 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1006,6 +1006,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring 
*tx_ring,
 struct sk_buff *skb)
 {
struct hnae3_handle *handle = tx_ring->tqp->handle;
+   struct hnae3_ae_dev *ae_dev;
struct vlan_ethhdr *vhdr;
int rc;
 
@@ -1013,10 +1014,13 @@ static int hns3_handle_vtags(struct hns3_enet_ring 
*tx_ring,
  skb_vlan_tag_present(skb)))
return 0;
 
-   /* Since HW limitation, if port based insert VLAN enabled, only one VLAN
-* header is allowed in skb, otherwise it will cause RAS error.
+   /* For HW limitation on HNAE3_DEVICE_VERSION_V2, if port based insert
+* VLAN enabled, only one VLAN header is allowed in skb, otherwise it
+* will cause RAS error.
 */
+   ae_dev = pci_get_drvdata(handle->pdev);
if (unlikely(skb_vlan_tagged_multi(skb) &&
+ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&
 handle->port_base_vlan_state ==
 HNAE3_PORT_BASE_VLAN_ENABLE))
return -EINVAL;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 7ce8be1..52a6f9b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -825,6 +825,7 @@ enum hclge_mac_vlan_cfg_sel {
 #define HCLGE_CFG_NIC_ROCE_SEL_B   4
 #define HCLGE_ACCEPT_TAG2_B5
 #define HCLGE_ACCEPT_UNTAG2_B  6
+#define HCLGE_TAG_SHIFT_MODE_EN_B  7
 #define HCLGE_VF_NUM_PER_BYTE  8
 
 struct hclge_vport_vtag_tx_cfg_cmd {
@@ -841,6 +842,8 @@ struct hclge_vport_vtag_tx_cfg_cmd {
 #define HCLGE_REM_TAG2_EN_B1
 #define HCLGE_SHOW_TAG1_EN_B   2
 #define HCLGE_SHOW_TAG2_EN_B   3
+#define HCLGE_DISCARD_TAG1_EN_B5
+#define HCLGE_DISCARD_TAG2_EN_B6
 struct hclge_vport_vtag_rx_cfg_cmd {
u8 vport_vlan_cfg;
u8 vf_offset;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index d83fcde..a70f44d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -8617,6 +8617,8 @@ static int hclge_set_vlan_tx_offload_cfg(struct 
hclge_vport *vport)
  vcfg->insert_tag1_en ? 1 : 0);
hnae3_set_bit(req-&

[PATCH V2 net-next 0/3] net: hns3: updates for -next

2020-12-05 Thread Huazhong Tan
There are some updates for the HNS3 ethernet driver.

#1 supports an extended promiscuous command which makes
promiscuous configuration more flexible, #2 adds ethtool
private flags to control whether enable tx unicast promisc.
#3 refine the vlan tag handling for port based vlan.

change log:
V2: modifies #2 suggested by Jakub Kicinski.
fixes some spelling mistake in #3.

previous version:
https://patchwork.kernel.org/project/netdevbpf/cover/1606997936-22166-1-git-send-email-tanhuazh...@huawei.com/

Guojia Liao (2):
  net: hns3: add support for extended promiscuous command
  net: hns3: refine the VLAN tag handle for port based VLAN

Jian Shen (1):
  net: hns3: add priv flags support to switch limit promisc mode

 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h|   1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|   8 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  11 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  86 
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  34 ---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 111 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  13 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |  18 +++-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |   7 ++
 9 files changed, 223 insertions(+), 66 deletions(-)

-- 
2.7.4



[PATCH V2 net-next 1/3] net: hns3: add support for extended promiscuous command

2020-12-05 Thread Huazhong Tan
From: Guojia Liao 

For DEVICE_VERSION_V2, the hardware supports enable tx and rx
promiscuous separately. But tx or rx promiscuous is active for
unicast, multicast and broadcast promiscuous simultaneously.
To support traffics between functions belong to the same port,
we always enable tx promiscuous for broadcast promiscuous, so
tx promiscuous for unicast and multicast promiscuous is also
enabled.

For DEVICE_VERSION_V3, the hardware decouples the above
relationship. Tx unicast promiscuous, rx unicast promiscuous,
tx multicast promiscuous, rx multicast promiscuous, tx broadcast
promiscuous and rx broadcast promiscuous can be enabled separately.

So add support for the new promiscuous command.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 31 +++-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 59 +-
 2 files changed, 41 insertions(+), 49 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 49cbd95..7ce8be1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -583,23 +583,26 @@ struct hclge_link_status_cmd {
u8 rsv[23];
 };
 
-struct hclge_promisc_param {
-   u8 vf_id;
-   u8 enable;
-};
+/* for DEVICE_VERSION_V1/2, reference to promisc cmd byte8 */
+#define HCLGE_PROMISC_EN_UC1
+#define HCLGE_PROMISC_EN_MC2
+#define HCLGE_PROMISC_EN_BC3
+#define HCLGE_PROMISC_TX_EN4
+#define HCLGE_PROMISC_RX_EN5
+
+/* for DEVICE_VERSION_V3, reference to promisc cmd byte10 */
+#define HCLGE_PROMISC_UC_RX_EN 2
+#define HCLGE_PROMISC_MC_RX_EN 3
+#define HCLGE_PROMISC_BC_RX_EN 4
+#define HCLGE_PROMISC_UC_TX_EN 5
+#define HCLGE_PROMISC_MC_TX_EN 6
+#define HCLGE_PROMISC_BC_TX_EN 7
 
-#define HCLGE_PROMISC_TX_EN_B  BIT(4)
-#define HCLGE_PROMISC_RX_EN_B  BIT(5)
-#define HCLGE_PROMISC_EN_B 1
-#define HCLGE_PROMISC_EN_ALL   0x7
-#define HCLGE_PROMISC_EN_UC0x1
-#define HCLGE_PROMISC_EN_MC0x2
-#define HCLGE_PROMISC_EN_BC0x4
 struct hclge_promisc_cfg_cmd {
-   u8 flag;
+   u8 promisc;
u8 vf_id;
-   __le16 rsv0;
-   u8 rsv1[20];
+   u8 extend_promisc;
+   u8 rsv0[21];
 };
 
 enum hclge_promisc_type {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index ca668a4..f4859ad 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -4826,61 +4826,50 @@ static int hclge_unmap_ring_frm_vector(struct 
hnae3_handle *handle, int vector,
return ret;
 }
 
-static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
- struct hclge_promisc_param *param)
+static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, u8 vf_id,
+ bool en_uc, bool en_mc, bool en_bc)
 {
struct hclge_promisc_cfg_cmd *req;
struct hclge_desc desc;
+   u8 promisc_cfg = 0;
int ret;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_CFG_PROMISC_MODE, false);
 
req = (struct hclge_promisc_cfg_cmd *)desc.data;
-   req->vf_id = param->vf_id;
+   req->vf_id = vf_id;
 
-   /* HCLGE_PROMISC_TX_EN_B and HCLGE_PROMISC_RX_EN_B are not supported on
-* pdev revision(0x20), new revision support them. The
-* value of this two fields will not return error when driver
-* send command to fireware in revision(0x20).
-*/
-   req->flag = (param->enable << HCLGE_PROMISC_EN_B) |
-   HCLGE_PROMISC_TX_EN_B | HCLGE_PROMISC_RX_EN_B;
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_RX_EN, en_uc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_RX_EN, en_mc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_RX_EN, en_bc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_TX_EN, en_uc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_TX_EN, en_mc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_TX_EN, en_bc ? 1 : 0);
+   req->extend_promisc = promisc_cfg;
+
+   /* to be compatible with DEVICE_VERSION_V1/2 */
+   promisc_cfg = 0;
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_UC, en_uc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_MC, en_mc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_BC, en_bc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_TX_EN, 1);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_RX_EN, 1);
+   req->promisc = promisc_cfg;
 
ret = hclge_cmd_send(>hw, , 1);
if (ret)
dev_err(>pdev->dev,
-   "failed to set vport %d promisc mode, ret = %d.\n",
-   param->vf_id, ret)

[PATCH net-next 2/3] net: hns3: add priv flags support to switch limit promisc mode

2020-12-03 Thread Huazhong Tan
From: Jian Shen 

Currently, the tx unicast promisc is always enabled when promisc
mode on. If tx unicast promisc on, a function will receive all
unicast packet from other functions belong to the same port.
Adds a ethtool private flags to control whether enable tx
unicast promisc. Then the function is able to filter the
unknown unicast packets from other function.

Signed-off-by: Jian Shen 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  8 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  4 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 87 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  8 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |  7 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  7 ++
 7 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h 
b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
index 1ffe8fa..fb5e884 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
@@ -110,6 +110,7 @@ struct hclge_vf_to_pf_msg {
u8 en_bc;
u8 en_uc;
u8 en_mc;
+   u8 en_limit_promisc;
};
struct {
u8 vector_id;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 78b4886..f30d81e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -719,6 +719,11 @@ struct hnae3_roce_private_info {
 #define HNAE3_UPE  (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
 #define HNAE3_MPE  (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
 
+enum hnae3_pflag {
+   HNAE3_PFLAG_LIMIT_PROMISC_ENABLE,
+   HNAE3_PFLAG_MAX
+};
+
 struct hnae3_handle {
struct hnae3_client *client;
struct pci_dev *pdev;
@@ -741,6 +746,9 @@ struct hnae3_handle {
 
/* Network interface message level enabled bits */
u32 msg_enable;
+
+   unsigned long supported_pflags;
+   unsigned long priv_flags;
 };
 
 #define hnae3_set_field(origin, mask, shift, val) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 1798c0a..9873fc4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4226,6 +4226,10 @@ static int hns3_client_init(struct hnae3_handle *handle)
 
set_bit(HNS3_NIC_STATE_INITED, >state);
 
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+   set_bit(HNAE3_PFLAG_LIMIT_PROMISC_ENABLE,
+   >supported_pflags);
+
if (netif_msg_drv(handle))
hns3_info_show(priv);
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 3cca3c1..34531c0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -18,6 +18,11 @@ struct hns3_sfp_type {
u8 ext_type;
 };
 
+struct hns3_pflag_desc {
+   char name[ETH_GSTRING_LEN];
+   void (*handler)(struct net_device *netdev, bool enable);
+};
+
 /* tqp related stats */
 #define HNS3_TQP_STAT(_string, _member){   \
.stats_string = _string,\
@@ -60,6 +65,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
 
+#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
+
 #define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
 
 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
@@ -395,6 +402,24 @@ static void hns3_self_test(struct net_device *ndev,
netif_dbg(h, drv, ndev, "self test end\n");
 }
 
+static void hns3_update_limit_promisc_mode(struct net_device *netdev,
+  bool enable)
+{
+   struct hnae3_handle *handle = hns3_get_handle(netdev);
+
+   if (enable)
+   set_bit(HNAE3_PFLAG_LIMIT_PROMISC_ENABLE, >priv_flags);
+   else
+   clear_bit(HNAE3_PFLAG_LIMIT_PROMISC_ENABLE,
+ >priv_flags);
+
+   hns3_request_update_promisc_mode(handle);
+}
+
+static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
+   { "limit_promisc",  hns3_update_limit_promisc_mode }
+};
+
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -411,6 +436,9 @@ static int hns3_get_sset_count(struct net_device *netdev, 
int stringset)
case ETH_SS_TEST:
return ops->get_sset_count(h, stringset);
 
+  

[PATCH net-next 3/3] net: hns3: refine the VLAN tag handle for port based VLAN

2020-12-03 Thread Huazhong Tan
From: Guojia Liao 

For DEVICE_VERSION_V2, the hardware only supports max two layer
VLAN tags, including port based tag inserted by hardware, tag in
tx buffer descriptor(get from skb->tci) and tag in packet.

For tranmist packet:
If port based VLAN disabled, and vf driver gets a VLAN tag from
skb, the VLAN tag must be filled to the Outer_VLAN_TAG field
(tag near to DMAC) of tx buffer descriptor, otherwise it may
be inserted after the tag in packet.

If port based VLAN enabled, and vf driver gets a VLAN tag from
skb, the VLAN tag must be filled to the VLAN_TAG field (tag
far to DMAC) of tx buffer descriptor, otherwise it may be
conflicted with port based VLAN, and raise a msix error event.

For receive packet:
The hardware will strip the VLAN tags and fill them in the
rx buffer descriptor, no matter port based VLAN enable or not.
Because port based VLAN tag is useless for stack, so vf driver
needs to discard the port based VLAN tag get from rx buffer
descriptor when port based VLAN enabled.

So the vf must know about the port based VLAN state.

For DEVICE_VERSION_V3, the hardware provides some new
configuration to improve it.

For tranmist packet:
when enable tag shift mode, hardware will handle
the VLAN tag in Outer_VLAN_TAG field as VLAN_TAG, so it
won't conflict with port based VLAN. And hardware also
make sure the tag before the tag in packet. So vf driver
doesn't need to specify the tag position according to the
port based VLAN state anymore.

For receive packet:
when enable discard mode, hardware will strip and discard the
port based VLAN tag, so the vf driver doesn't need to
identify it from rx buffer descriptor.

So modify the port based VLAN configuration, simplify the process
for vf handling the VLAN tag.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  8 +++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  3 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 46 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 13 +++---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 11 +-
 5 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 9873fc4..aef7b24 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1006,6 +1006,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring 
*tx_ring,
 struct sk_buff *skb)
 {
struct hnae3_handle *handle = tx_ring->tqp->handle;
+   struct hnae3_ae_dev *ae_dev;
struct vlan_ethhdr *vhdr;
int rc;
 
@@ -1013,10 +1014,13 @@ static int hns3_handle_vtags(struct hns3_enet_ring 
*tx_ring,
  skb_vlan_tag_present(skb)))
return 0;
 
-   /* Since HW limitation, if port based insert VLAN enabled, only one VLAN
-* header is allowed in skb, otherwise it will cause RAS error.
+   /* For HW limitation on HNAE3_DEVICE_VERSION_V2, if port based insert
+* VLAN enabled, only one VLAN header is allowed in skb, otherwise it
+* will cause RAS error.
 */
+   ae_dev = pci_get_drvdata(handle->pdev);
if (unlikely(skb_vlan_tagged_multi(skb) &&
+ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2 &&
 handle->port_base_vlan_state ==
 HNAE3_PORT_BASE_VLAN_ENABLE))
return -EINVAL;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 7ce8be1..52a6f9b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -825,6 +825,7 @@ enum hclge_mac_vlan_cfg_sel {
 #define HCLGE_CFG_NIC_ROCE_SEL_B   4
 #define HCLGE_ACCEPT_TAG2_B5
 #define HCLGE_ACCEPT_UNTAG2_B  6
+#define HCLGE_TAG_SHIFT_MODE_EN_B  7
 #define HCLGE_VF_NUM_PER_BYTE  8
 
 struct hclge_vport_vtag_tx_cfg_cmd {
@@ -841,6 +842,8 @@ struct hclge_vport_vtag_tx_cfg_cmd {
 #define HCLGE_REM_TAG2_EN_B1
 #define HCLGE_SHOW_TAG1_EN_B   2
 #define HCLGE_SHOW_TAG2_EN_B   3
+#define HCLGE_DISCARD_TAG1_EN_B5
+#define HCLGE_DISCARD_TAG2_EN_B6
 struct hclge_vport_vtag_rx_cfg_cmd {
u8 vport_vlan_cfg;
u8 vf_offset;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 7d511df..cfa0be6 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -8617,6 +8617,8 @@ static int hclge_set_vlan_tx_offload_cfg(struct 
hclge_vport *vport)
  vcfg->insert_tag1_en ? 1 : 0);
hnae3_set_bit(req-&

[PATCH net-next 0/3] net: hns3: updates for -next

2020-12-03 Thread Huazhong Tan
There are some updates for the HNS3 ethernet driver.

#1 supports an extended promiscuous command which makes
promiscuous configuration more flexible, #2 adds ethtool
private flags to control whether enable tx unicast promisc.
#3 refine the vlan tag handling for port based vlan.

Guojia Liao (2):
  net: hns3: add support for extended promiscuous command
  net: hns3: refine the VLAN tag handle for port based VLAN

Jian Shen (1):
  net: hns3: add priv flags support to switch limit promisc mode

 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h|   1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|   8 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  12 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  87 
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  34 ---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 111 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  13 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c |  18 +++-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |   7 ++
 9 files changed, 225 insertions(+), 66 deletions(-)

-- 
2.7.4



[PATCH net-next 1/3] net: hns3: add support for extended promiscuous command

2020-12-03 Thread Huazhong Tan
From: Guojia Liao 

For DEVICE_VERSION_V2, the hardware supports enable tx and rx
promiscuous separately. But tx or rx promiscuous is active for
unicast, multicast and broadcast promiscuous simultaneously.
To support traffics between functions belong to the same port,
we always enable tx promiscuous for broadcast promiscuous, so
tx promiscuous for unicast and multicast promiscuous is also
enabled.

For DEVICE_VERSION_V3, the hardware decouples the above
relationship. Tx unicast promiscuous, rx unicast promiscuous,
tx multicast promiscuous, rx multicast promiscuous, tx broadcast
promiscuous and rx broadcast promiscuous can be enabled separately.

So add support for the new promiscuous command.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 31 +++-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 59 +-
 2 files changed, 41 insertions(+), 49 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 49cbd95..7ce8be1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -583,23 +583,26 @@ struct hclge_link_status_cmd {
u8 rsv[23];
 };
 
-struct hclge_promisc_param {
-   u8 vf_id;
-   u8 enable;
-};
+/* for DEVICE_VERSION_V1/2, reference to promisc cmd byte8 */
+#define HCLGE_PROMISC_EN_UC1
+#define HCLGE_PROMISC_EN_MC2
+#define HCLGE_PROMISC_EN_BC3
+#define HCLGE_PROMISC_TX_EN4
+#define HCLGE_PROMISC_RX_EN5
+
+/* for DEVICE_VERSION_V3, reference to promisc cmd byte10 */
+#define HCLGE_PROMISC_UC_RX_EN 2
+#define HCLGE_PROMISC_MC_RX_EN 3
+#define HCLGE_PROMISC_BC_RX_EN 4
+#define HCLGE_PROMISC_UC_TX_EN 5
+#define HCLGE_PROMISC_MC_TX_EN 6
+#define HCLGE_PROMISC_BC_TX_EN 7
 
-#define HCLGE_PROMISC_TX_EN_B  BIT(4)
-#define HCLGE_PROMISC_RX_EN_B  BIT(5)
-#define HCLGE_PROMISC_EN_B 1
-#define HCLGE_PROMISC_EN_ALL   0x7
-#define HCLGE_PROMISC_EN_UC0x1
-#define HCLGE_PROMISC_EN_MC0x2
-#define HCLGE_PROMISC_EN_BC0x4
 struct hclge_promisc_cfg_cmd {
-   u8 flag;
+   u8 promisc;
u8 vf_id;
-   __le16 rsv0;
-   u8 rsv1[20];
+   u8 extend_promisc;
+   u8 rsv0[21];
 };
 
 enum hclge_promisc_type {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index ca668a4..f4859ad 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -4826,61 +4826,50 @@ static int hclge_unmap_ring_frm_vector(struct 
hnae3_handle *handle, int vector,
return ret;
 }
 
-static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
- struct hclge_promisc_param *param)
+static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, u8 vf_id,
+ bool en_uc, bool en_mc, bool en_bc)
 {
struct hclge_promisc_cfg_cmd *req;
struct hclge_desc desc;
+   u8 promisc_cfg = 0;
int ret;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_CFG_PROMISC_MODE, false);
 
req = (struct hclge_promisc_cfg_cmd *)desc.data;
-   req->vf_id = param->vf_id;
+   req->vf_id = vf_id;
 
-   /* HCLGE_PROMISC_TX_EN_B and HCLGE_PROMISC_RX_EN_B are not supported on
-* pdev revision(0x20), new revision support them. The
-* value of this two fields will not return error when driver
-* send command to fireware in revision(0x20).
-*/
-   req->flag = (param->enable << HCLGE_PROMISC_EN_B) |
-   HCLGE_PROMISC_TX_EN_B | HCLGE_PROMISC_RX_EN_B;
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_RX_EN, en_uc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_RX_EN, en_mc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_RX_EN, en_bc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_TX_EN, en_uc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_TX_EN, en_mc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_TX_EN, en_bc ? 1 : 0);
+   req->extend_promisc = promisc_cfg;
+
+   /* to be compatible with DEVICE_VERSION_V1/2 */
+   promisc_cfg = 0;
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_UC, en_uc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_MC, en_mc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_BC, en_bc ? 1 : 0);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_TX_EN, 1);
+   hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_RX_EN, 1);
+   req->promisc = promisc_cfg;
 
ret = hclge_cmd_send(>hw, , 1);
if (ret)
dev_err(>pdev->dev,
-   "failed to set vport %d promisc mode, ret = %d.\n",
-   param->vf_id, ret)

[PATCH V2 net-next 2/7] net: hns3: add support for TX hardware checksum offload

2020-11-28 Thread Huazhong Tan
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 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  6 +--
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  6 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 62 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 10 +++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |  2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  2 +-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |  2 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  2 +-
 8 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f6fac24..0632607 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -81,7 +81,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,
@@ -113,8 +113,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 a5ebca8..044552d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -178,6 +178,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
u32 tx_index, rx_index;
u32 q_num, value;
dma_addr_t addr;
+   u16 mss_hw_csum;
int cnt;
 
cnt = sscanf(_buf[8], "%u %u", _num, _index);
@@ -206,6 +207,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
 
tx_desc = >desc[tx_index];
addr = le64_to_cpu(tx_desc->addr);
+   mss_hw_csum = le16_to_cpu(tx_desc->tx.mss_hw_csum);
dev_info(dev, "TX Queue Num: %u, BD Index: %u\n", q_num, tx_index);
dev_info(dev, "(TX)addr: %pad\n", );
dev_info(dev, "(TX)vlan_tag: %u\n", le16_to_cpu(tx_desc->tx.vlan_tag));
@@ -225,7 +227,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
dev_info(dev, "(TX)paylen: %u\n", le32_to_cpu(tx_desc->tx.paylen));
dev_info(dev, "(TX)vld_ra_ri: %u\n",
 le16_to_cpu(tx_desc->tx.bdtp_fe_sc_vld_ra_ri));
-   dev_info(dev, "(TX)mss: %u\n", le16_to_cpu(tx_desc->tx.mss));
+   dev_info(dev, "(TX)mss_hw_csum: %u\n", mss_hw_csum);
 
ring = >ring[q_num + h->kinfo.num_tqps];
value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_TAIL_REG);
@@ -324,6 +326,8 @@ static void hns3_dbg_dev_caps(struct hnae3_handle *h)
 test_bit(HNAE3_DEV_SUPPORT_PTP_B, caps) ? "yes" : "no");
dev_info(>pdev->dev, "support INT QL: %s\n",
 test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no");
+   dev_info(>pdev->dev, "support HW TX csum: %s\n",
+test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, caps) ? "yes" : "no");
 }
 
 static void hns3_dbg_dev_specs(struct hnae3_handle *h)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 1647877..904328e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1055,15 +1055,31 @@ 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 f

[PATCH V2 net-next 7/7] net: hns3: keep MAC pause mode when multiple TCs are enabled

2020-11-28 Thread Huazhong Tan
From: Yonglong Liu 

Bellow HNAE3_DEVICE_VERSION_V3, MAC pause mode just support one
TC, when enabled multiple TCs, force enable PFC mode.

HNAE3_DEVICE_VERSION_V3 can support MAC pause mode on multiple
TCs, so when enable multiple TCs, just keep MAC pause mode,
and enable PFC mode just according to the user settings.

Signed-off-by: Yonglong Liu 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 23 +-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 54767b0..b1026cd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -715,7 +715,7 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
}
 }
 
-static void hclge_pfc_info_init(struct hclge_dev *hdev)
+static void hclge_update_fc_mode_by_dcb_flag(struct hclge_dev *hdev)
 {
if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) {
if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
@@ -733,6 +733,27 @@ static void hclge_pfc_info_init(struct hclge_dev *hdev)
}
 }
 
+static void hclge_update_fc_mode(struct hclge_dev *hdev)
+{
+   if (!hdev->tm_info.pfc_en) {
+   hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
+   return;
+   }
+
+   if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hdev->tm_info.fc_mode = HCLGE_FC_PFC;
+   }
+}
+
+static void hclge_pfc_info_init(struct hclge_dev *hdev)
+{
+   if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+   hclge_update_fc_mode(hdev);
+   else
+   hclge_update_fc_mode_by_dcb_flag(hdev);
+}
+
 static void hclge_tm_schd_info_init(struct hclge_dev *hdev)
 {
hclge_tm_pg_info_init(hdev);
-- 
2.7.4



[PATCH V2 net-next 4/7] net: hns3: add udp tunnel checksum segmentation support

2020-11-28 Thread Huazhong Tan
For the device who has the capability to handle udp tunnel
checksum segmentation, add support for it.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  6 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 24 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  4 +++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |  2 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |  2 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  1 +
 8 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 0632607..78b4886 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -87,6 +87,7 @@ enum HNAE3_DEV_CAP_BITS {
HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B,
HNAE3_DEV_SUPPORT_HW_PAD_B,
HNAE3_DEV_SUPPORT_STASH_B,
+   HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,
 };
 
 #define hnae3_dev_fd_supported(hdev) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index 044552d..cb0cc6d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -224,7 +224,8 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
-   dev_info(dev, "(TX)paylen: %u\n", le32_to_cpu(tx_desc->tx.paylen));
+   dev_info(dev, "(TX)paylen_ol4cs: %u\n",
+le32_to_cpu(tx_desc->tx.paylen_ol4cs));
dev_info(dev, "(TX)vld_ra_ri: %u\n",
 le16_to_cpu(tx_desc->tx.bdtp_fe_sc_vld_ra_ri));
dev_info(dev, "(TX)mss_hw_csum: %u\n", mss_hw_csum);
@@ -328,6 +329,9 @@ static void hns3_dbg_dev_caps(struct hnae3_handle *h)
 test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no");
dev_info(>pdev->dev, "support HW TX csum: %s\n",
 test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, caps) ? "yes" : "no");
+   dev_info(>pdev->dev, "support UDP tunnel csum: %s\n",
+test_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, caps) ?
+"yes" : "no");
 }
 
 static void hns3_dbg_dev_specs(struct hnae3_handle *h)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 34b8a7d..3ad7f98 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -695,7 +695,7 @@ void hns3_enable_vlan_filter(struct net_device *netdev, 
bool enable)
}
 }
 
-static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
+static int hns3_set_tso(struct sk_buff *skb, u32 *paylen_fdop_ol4cs,
u16 *mss, u32 *type_cs_vlan_tso)
 {
u32 l4_offset, hdr_len;
@@ -723,7 +723,8 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
/* tunnel packet */
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
 SKB_GSO_GRE_CSUM |
-SKB_GSO_UDP_TUNNEL)) {
+SKB_GSO_UDP_TUNNEL |
+SKB_GSO_UDP_TUNNEL_CSUM)) {
/* reset l3 pointers from outer to inner headers */
l3.hdr = skb_inner_network_header(skb);
l4.hdr = skb_inner_transport_header(skb);
@@ -752,9 +753,13 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
}
 
/* find the txbd field values */
-   *paylen = skb->len - hdr_len;
+   *paylen_fdop_ol4cs = skb->len - hdr_len;
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_TSO_B, 1);
 
+   /* offload outer UDP header checksum */
+   if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
+   hns3_set_field(*paylen_fdop_ol4cs, HNS3_TXD_OL4CS_B, 1);
+
/* get MSS for TSO */
*mss = skb_shinfo(skb)->gso_size;
 
@@ -1065,8 +1070,8 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
  struct sk_buff *skb, struct hns3_desc *desc)
 {
u32 ol_type_vlan_len_msec = 0;
+   u32 paylen_ol4cs = skb->len;
u32 type_cs_vlan_tso = 0;
-   u32 paylen = skb->len;
u16 mss_hw_csum = 0;
u16 inner_vtag = 0;
u16 out_vtag = 0;
@@ -1125,7 +1130,7 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,

[PATCH V2 net-next 5/7] net: hns3: add more info to hns3_dbg_bd_info()

2020-11-28 Thread Huazhong Tan
Since TX hardware checksum and RX completion checksum have been
supported now, so add related information in hns3_dbg_bd_info().

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 50 +-
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index cb0cc6d..cb26742 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -179,6 +179,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
u32 q_num, value;
dma_addr_t addr;
u16 mss_hw_csum;
+   u32 l234info;
int cnt;
 
cnt = sscanf(_buf[8], "%u %u", _num, _index);
@@ -213,17 +214,35 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
dev_info(dev, "(TX)vlan_tag: %u\n", le16_to_cpu(tx_desc->tx.vlan_tag));
dev_info(dev, "(TX)send_size: %u\n",
 le16_to_cpu(tx_desc->tx.send_size));
-   dev_info(dev, "(TX)vlan_tso: %u\n", tx_desc->tx.type_cs_vlan_tso);
-   dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len);
-   dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len);
-   dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len);
+
+   if (mss_hw_csum & BIT(HNS3_TXD_HW_CS_B)) {
+   u32 offset = le32_to_cpu(tx_desc->tx.ol_type_vlan_len_msec);
+   u32 start = le32_to_cpu(tx_desc->tx.type_cs_vlan_tso_len);
+
+   dev_info(dev, "(TX)csum start: %u\n",
+hnae3_get_field(start,
+HNS3_TXD_CSUM_START_M,
+HNS3_TXD_CSUM_START_S));
+   dev_info(dev, "(TX)csum offset: %u\n",
+hnae3_get_field(offset,
+HNS3_TXD_CSUM_OFFSET_M,
+HNS3_TXD_CSUM_OFFSET_S));
+   } else {
+   dev_info(dev, "(TX)vlan_tso: %u\n",
+tx_desc->tx.type_cs_vlan_tso);
+   dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len);
+   dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len);
+   dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len);
+   dev_info(dev, "(TX)vlan_msec: %u\n",
+tx_desc->tx.ol_type_vlan_msec);
+   dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
+   dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
+   dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
+   }
+
dev_info(dev, "(TX)vlan_tag: %u\n",
 le16_to_cpu(tx_desc->tx.outer_vlan_tag));
dev_info(dev, "(TX)tv: %u\n", le16_to_cpu(tx_desc->tx.tv));
-   dev_info(dev, "(TX)vlan_msec: %u\n", tx_desc->tx.ol_type_vlan_msec);
-   dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
-   dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
-   dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
dev_info(dev, "(TX)paylen_ol4cs: %u\n",
 le32_to_cpu(tx_desc->tx.paylen_ol4cs));
dev_info(dev, "(TX)vld_ra_ri: %u\n",
@@ -236,10 +255,21 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
rx_desc = >desc[rx_index];
 
addr = le64_to_cpu(rx_desc->addr);
+   l234info = le32_to_cpu(rx_desc->rx.l234_info);
dev_info(dev, "RX Queue Num: %u, BD Index: %u\n", q_num, rx_index);
dev_info(dev, "(RX)addr: %pad\n", );
-   dev_info(dev, "(RX)l234_info: %u\n",
-le32_to_cpu(rx_desc->rx.l234_info));
+   dev_info(dev, "(RX)l234_info: %u\n", l234info);
+
+   if (l234info & BIT(HNS3_RXD_L2_CSUM_B)) {
+   u32 lo, hi;
+
+   lo = hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_L_M,
+HNS3_RXD_L2_CSUM_L_S);
+   hi = hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_H_M,
+HNS3_RXD_L2_CSUM_H_S);
+   dev_info(dev, "(RX)csum: %u\n", lo | hi << 8);
+   }
+
dev_info(dev, "(RX)pkt_len: %u\n", le16_to_cpu(rx_desc->rx.pkt_len));
dev_info(dev, "(RX)size: %u\n", le16_to_cpu(rx_desc->rx.size));
dev_info(dev, "(RX)rss_hash: %u\n", le32_to_cpu(rx_desc->rx.rss_hash));
-- 
2.7.4



[PATCH V2 net-next 3/7] net: hns3: remove unsupported NETIF_F_GSO_UDP_TUNNEL_CSUM

2020-11-28 Thread Huazhong Tan
Currently, device V1 and V2 do not support segmentation
offload for UDP based tunnel packet who needs outer UDP
checksum offload, so there is a workaround in the driver
to set the checksum of the outer UDP checksum as zero. This
is not what the user wants, so remove this feature for
device V1 and V2, add support for it later(when the device
has the ability to do that).

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 24 +---
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 904328e..34b8a7d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -723,17 +723,7 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
/* tunnel packet */
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
 SKB_GSO_GRE_CSUM |
-SKB_GSO_UDP_TUNNEL |
-SKB_GSO_UDP_TUNNEL_CSUM)) {
-   if ((!(skb_shinfo(skb)->gso_type &
-   SKB_GSO_PARTIAL)) &&
-   (skb_shinfo(skb)->gso_type &
-   SKB_GSO_UDP_TUNNEL_CSUM)) {
-   /* Software should clear the udp's checksum
-* field when tso is needed.
-*/
-   l4.udp->check = 0;
-   }
+SKB_GSO_UDP_TUNNEL)) {
/* reset l3 pointers from outer to inner headers */
l3.hdr = skb_inner_network_header(skb);
l4.hdr = skb_inner_transport_header(skb);
@@ -2357,8 +2347,7 @@ static void hns3_set_default_feature(struct net_device 
*netdev)
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 |
-   NETIF_F_TSO_MANGLEID | NETIF_F_FRAGLIST;
+   NETIF_F_SCTP_CRC | NETIF_F_TSO_MANGLEID | NETIF_F_FRAGLIST;
 
netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
 
@@ -2367,23 +2356,20 @@ static void hns3_set_default_feature(struct net_device 
*netdev)
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;
+   NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
 
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;
+   NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
 
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 |
-   NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC |
-   NETIF_F_FRAGLIST;
+   NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
 
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
netdev->hw_features |= NETIF_F_GRO_HW;
-- 
2.7.4



[PATCH V2 net-next 1/7] net: hns3: add support for RX completion checksum

2020-11-27 Thread Huazhong Tan
In some cases (for example ip fragment), hardware will
calculate the checksum of whole packet in RX, and setup
the HNS3_RXD_L2_CSUM_B flag in the descriptor, so add
support to utilize this checksum.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 21 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  7 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  1 +
 3 files changed, 29 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 632ad42..1647877 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2798,6 +2798,22 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 
l234info)
return 0;
 }
 
+static void hns3_checksum_complete(struct hns3_enet_ring *ring,
+  struct sk_buff *skb, u32 l234info)
+{
+   u32 lo, hi;
+
+   u64_stats_update_begin(>syncp);
+   ring->stats.csum_complete++;
+   u64_stats_update_end(>syncp);
+   skb->ip_summed = CHECKSUM_COMPLETE;
+   lo = hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_L_M,
+HNS3_RXD_L2_CSUM_L_S);
+   hi = hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_H_M,
+HNS3_RXD_L2_CSUM_H_S);
+   skb->csum = csum_unfold((__force __sum16)(lo | hi << 8));
+}
+
 static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
 u32 l234info, u32 bd_base_info, u32 ol_info)
 {
@@ -2812,6 +2828,11 @@ static void hns3_rx_checksum(struct hns3_enet_ring 
*ring, struct sk_buff *skb,
if (!(netdev->features & NETIF_F_RXCSUM))
return;
 
+   if (l234info & BIT(HNS3_RXD_L2_CSUM_B)) {
+   hns3_checksum_complete(ring, skb, l234info);
+   return;
+   }
+
/* check if hardware has done checksum */
if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
return;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 8d33652..40681a0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -82,6 +82,12 @@ enum hns3_nic_state {
 #define HNS3_RXD_STRP_TAGP_S   13
 #define HNS3_RXD_STRP_TAGP_M   (0x3 << HNS3_RXD_STRP_TAGP_S)
 
+#define HNS3_RXD_L2_CSUM_B 15
+#define HNS3_RXD_L2_CSUM_L_S   4
+#define HNS3_RXD_L2_CSUM_L_M   (0xff << HNS3_RXD_L2_CSUM_L_S)
+#define HNS3_RXD_L2_CSUM_H_S   24
+#define HNS3_RXD_L2_CSUM_H_M   (0xff << HNS3_RXD_L2_CSUM_H_S)
+
 #define HNS3_RXD_L2E_B 16
 #define HNS3_RXD_L3E_B 17
 #define HNS3_RXD_L4E_B 18
@@ -371,6 +377,7 @@ struct ring_stats {
u64 err_bd_num;
u64 l2_err;
u64 l3l4_csum_err;
+   u64 csum_complete;
u64 rx_multicast;
u64 non_reuse_pg;
};
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index c30d5d3..3cca3c1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -55,6 +55,7 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("err_bd_num", err_bd_num),
HNS3_TQP_STAT("l2_err", l2_err),
HNS3_TQP_STAT("l3l4_csum_err", l3l4_csum_err),
+   HNS3_TQP_STAT("csum_complete", csum_complete),
HNS3_TQP_STAT("multicast", rx_multicast),
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
-- 
2.7.4



[PATCH V2 net-next 0/7] net: hns3: updates for -next

2020-11-27 Thread Huazhong Tan
This series includes some updates for the HNS3 ethernet driver.

#1~#6: add some updates related to the checksum offload.
#7: add support for multiple TCs' MAC pauce mode.

change log:
V2: fixes some sparse errors in #1 & #5.

previous version:
V1: 
https://patchwork.kernel.org/project/netdevbpf/cover/1606466842-57749-1-git-send-email-tanhuazh...@huawei.com/

Huazhong Tan (6):
  net: hns3: add support for RX completion checksum
  net: hns3: add support for TX hardware checksum offload
  net: hns3: remove unsupported NETIF_F_GSO_UDP_TUNNEL_CSUM
  net: hns3: add udp tunnel checksum segmentation support
  net: hns3: add more info to hns3_dbg_bd_info()
  net: hns3: add a check for devcie's verion in hns3_tunnel_csum_bug()

Yonglong Liu (1):
  net: hns3: keep MAC pause mode when multiple TCs are enabled

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|   7 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  62 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 131 -
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  21 +++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |   1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |   4 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   3 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  23 +++-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |   4 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |   3 +-
 10 files changed, 207 insertions(+), 52 deletions(-)

-- 
2.7.4



[PATCH V2 net-next 6/7] net: hns3: add a check for devcie's verion in hns3_tunnel_csum_bug()

2020-11-27 Thread Huazhong Tan
For the device whose version is above V3(include V3), the hardware
can do checksum offload for the non-tunnel udp packet, who has
a dest port as the IANA assigned. So add a check for devcie's verion
in hns3_tunnel_csum_bug().

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 3ad7f98..1798c0a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -828,8 +828,16 @@ static int hns3_get_l4_protocol(struct sk_buff *skb, u8 
*ol4_proto,
  */
 static bool hns3_tunnel_csum_bug(struct sk_buff *skb)
 {
+   struct hns3_nic_priv *priv = netdev_priv(skb->dev);
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
union l4_hdr_info l4;
 
+   /* device version above V3(include V3), the hardware can
+* do this checksum offload.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+   return false;
+
l4.hdr = skb_transport_header(skb);
 
if (!(!skb->encapsulation &&
-- 
2.7.4



[PATCH net-next 3/7] net: hns3: remove unsupported NETIF_F_GSO_UDP_TUNNEL_CSUM

2020-11-27 Thread Huazhong Tan
Currently, device V1 and V2 do not support segmentation
offload for UDP based tunnel packet who needs outer UDP
checksum offload, so there is a workaround in the driver
to set the checksum of the outer UDP checksum as zero. This
is not what the user wants, so remove this feature for
device V1 and V2, add support for it later(when the device
has the ability to do that).

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 24 +---
 1 file changed, 5 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index e022bea..850cd3fa 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -723,17 +723,7 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
/* tunnel packet */
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
 SKB_GSO_GRE_CSUM |
-SKB_GSO_UDP_TUNNEL |
-SKB_GSO_UDP_TUNNEL_CSUM)) {
-   if ((!(skb_shinfo(skb)->gso_type &
-   SKB_GSO_PARTIAL)) &&
-   (skb_shinfo(skb)->gso_type &
-   SKB_GSO_UDP_TUNNEL_CSUM)) {
-   /* Software should clear the udp's checksum
-* field when tso is needed.
-*/
-   l4.udp->check = 0;
-   }
+SKB_GSO_UDP_TUNNEL)) {
/* reset l3 pointers from outer to inner headers */
l3.hdr = skb_inner_network_header(skb);
l4.hdr = skb_inner_transport_header(skb);
@@ -2357,8 +2347,7 @@ static void hns3_set_default_feature(struct net_device 
*netdev)
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 |
-   NETIF_F_TSO_MANGLEID | NETIF_F_FRAGLIST;
+   NETIF_F_SCTP_CRC | NETIF_F_TSO_MANGLEID | NETIF_F_FRAGLIST;
 
netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
 
@@ -2367,23 +2356,20 @@ static void hns3_set_default_feature(struct net_device 
*netdev)
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;
+   NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
 
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;
+   NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
 
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 |
-   NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC |
-   NETIF_F_FRAGLIST;
+   NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;
 
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
netdev->hw_features |= NETIF_F_GRO_HW;
-- 
2.7.4



[PATCH net-next 4/7] net: hns3: add udp tunnel checksum segmentation support

2020-11-27 Thread Huazhong Tan
For the device who has the capability to handle udp tunnel
checksum segmentation, add support for it.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  6 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 24 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  4 +++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |  2 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |  2 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  1 +
 8 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 0632607..78b4886 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -87,6 +87,7 @@ enum HNAE3_DEV_CAP_BITS {
HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B,
HNAE3_DEV_SUPPORT_HW_PAD_B,
HNAE3_DEV_SUPPORT_STASH_B,
+   HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,
 };
 
 #define hnae3_dev_fd_supported(hdev) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index 044552d..cb0cc6d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -224,7 +224,8 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
-   dev_info(dev, "(TX)paylen: %u\n", le32_to_cpu(tx_desc->tx.paylen));
+   dev_info(dev, "(TX)paylen_ol4cs: %u\n",
+le32_to_cpu(tx_desc->tx.paylen_ol4cs));
dev_info(dev, "(TX)vld_ra_ri: %u\n",
 le16_to_cpu(tx_desc->tx.bdtp_fe_sc_vld_ra_ri));
dev_info(dev, "(TX)mss_hw_csum: %u\n", mss_hw_csum);
@@ -328,6 +329,9 @@ static void hns3_dbg_dev_caps(struct hnae3_handle *h)
 test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no");
dev_info(>pdev->dev, "support HW TX csum: %s\n",
 test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, caps) ? "yes" : "no");
+   dev_info(>pdev->dev, "support UDP tunnel csum: %s\n",
+test_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, caps) ?
+"yes" : "no");
 }
 
 static void hns3_dbg_dev_specs(struct hnae3_handle *h)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 850cd3fa..07bdb3d5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -695,7 +695,7 @@ void hns3_enable_vlan_filter(struct net_device *netdev, 
bool enable)
}
 }
 
-static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
+static int hns3_set_tso(struct sk_buff *skb, u32 *paylen_fdop_ol4cs,
u16 *mss, u32 *type_cs_vlan_tso)
 {
u32 l4_offset, hdr_len;
@@ -723,7 +723,8 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
/* tunnel packet */
if (skb_shinfo(skb)->gso_type & (SKB_GSO_GRE |
 SKB_GSO_GRE_CSUM |
-SKB_GSO_UDP_TUNNEL)) {
+SKB_GSO_UDP_TUNNEL |
+SKB_GSO_UDP_TUNNEL_CSUM)) {
/* reset l3 pointers from outer to inner headers */
l3.hdr = skb_inner_network_header(skb);
l4.hdr = skb_inner_transport_header(skb);
@@ -752,9 +753,13 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
}
 
/* find the txbd field values */
-   *paylen = skb->len - hdr_len;
+   *paylen_fdop_ol4cs = skb->len - hdr_len;
hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_TSO_B, 1);
 
+   /* offload outer UDP header checksum */
+   if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)
+   hns3_set_field(*paylen_fdop_ol4cs, HNS3_TXD_OL4CS_B, 1);
+
/* get MSS for TSO */
*mss = skb_shinfo(skb)->gso_size;
 
@@ -1065,8 +1070,8 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,
  struct sk_buff *skb, struct hns3_desc *desc)
 {
u32 ol_type_vlan_len_msec = 0;
+   u32 paylen_ol4cs = skb->len;
u32 type_cs_vlan_tso = 0;
-   u32 paylen = skb->len;
u16 mss_hw_csum = 0;
u16 inner_vtag = 0;
u16 out_vtag = 0;
@@ -1125,7 +1130,7 @@ static int hns3_fill_skb_desc(struct hns3_enet_ring *ring,

[PATCH net-next 5/7] net: hns3: add more info to hns3_dbg_bd_info()

2020-11-27 Thread Huazhong Tan
Since TX hardware checksum and RX completion checksum have been
supported now, so add related information in hns3_dbg_bd_info().

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 50 +-
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index cb0cc6d..3b27cab 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -179,6 +179,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
u32 q_num, value;
dma_addr_t addr;
u16 mss_hw_csum;
+   u32 l234info;
int cnt;
 
cnt = sscanf(_buf[8], "%u %u", _num, _index);
@@ -213,17 +214,35 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
dev_info(dev, "(TX)vlan_tag: %u\n", le16_to_cpu(tx_desc->tx.vlan_tag));
dev_info(dev, "(TX)send_size: %u\n",
 le16_to_cpu(tx_desc->tx.send_size));
-   dev_info(dev, "(TX)vlan_tso: %u\n", tx_desc->tx.type_cs_vlan_tso);
-   dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len);
-   dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len);
-   dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len);
+
+   if (mss_hw_csum & BIT(HNS3_TXD_HW_CS_B)) {
+   u32 offset = le32_to_cpu(tx_desc->tx.ol_type_vlan_len_msec);
+   u32 start = le32_to_cpu(tx_desc->tx.type_cs_vlan_tso_len);
+
+   dev_info(dev, "(TX)csum start: %u\n",
+hnae3_get_field(start,
+HNS3_TXD_CSUM_START_M,
+HNS3_TXD_CSUM_START_S));
+   dev_info(dev, "(TX)csum offset: %u\n",
+hnae3_get_field(offset,
+HNS3_TXD_CSUM_OFFSET_M,
+HNS3_TXD_CSUM_OFFSET_S));
+   } else {
+   dev_info(dev, "(TX)vlan_tso: %u\n",
+tx_desc->tx.type_cs_vlan_tso);
+   dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len);
+   dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len);
+   dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len);
+   dev_info(dev, "(TX)vlan_msec: %u\n",
+tx_desc->tx.ol_type_vlan_msec);
+   dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
+   dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
+   dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
+   }
+
dev_info(dev, "(TX)vlan_tag: %u\n",
 le16_to_cpu(tx_desc->tx.outer_vlan_tag));
dev_info(dev, "(TX)tv: %u\n", le16_to_cpu(tx_desc->tx.tv));
-   dev_info(dev, "(TX)vlan_msec: %u\n", tx_desc->tx.ol_type_vlan_msec);
-   dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len);
-   dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len);
-   dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len);
dev_info(dev, "(TX)paylen_ol4cs: %u\n",
 le32_to_cpu(tx_desc->tx.paylen_ol4cs));
dev_info(dev, "(TX)vld_ra_ri: %u\n",
@@ -236,10 +255,21 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
rx_desc = >desc[rx_index];
 
addr = le64_to_cpu(rx_desc->addr);
+   l234info = le32_to_cpu(rx_desc->rx.l234_info);
dev_info(dev, "RX Queue Num: %u, BD Index: %u\n", q_num, rx_index);
dev_info(dev, "(RX)addr: %pad\n", );
-   dev_info(dev, "(RX)l234_info: %u\n",
-le32_to_cpu(rx_desc->rx.l234_info));
+   dev_info(dev, "(RX)l234_info: %u\n", l234info);
+
+   if (l234info & BIT(HNS3_RXD_L2_CSUM_B)) {
+   __sum16 csum;
+
+   csum = hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_L_M,
+  HNS3_RXD_L2_CSUM_L_S);
+   csum |= hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_H_M,
+   HNS3_RXD_L2_CSUM_H_S) << 8;
+   dev_info(dev, "(RX)csum: %u\n", csum);
+   }
+
dev_info(dev, "(RX)pkt_len: %u\n", le16_to_cpu(rx_desc->rx.pkt_len));
dev_info(dev, "(RX)size: %u\n", le16_to_cpu(rx_desc->rx.size));
dev_info(dev, "(RX)rss_hash: %u\n", le32_to_cpu(rx_desc->rx.rss_hash));
-- 
2.7.4



[PATCH net-next 2/7] net: hns3: add support for TX hardware checksum offload

2020-11-27 Thread Huazhong Tan
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 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  6 +--
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  6 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 62 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 10 +++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |  2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  2 +-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |  2 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  2 +-
 8 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f6fac24..0632607 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -81,7 +81,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,
@@ -113,8 +113,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 a5ebca8..044552d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -178,6 +178,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
u32 tx_index, rx_index;
u32 q_num, value;
dma_addr_t addr;
+   u16 mss_hw_csum;
int cnt;
 
cnt = sscanf(_buf[8], "%u %u", _num, _index);
@@ -206,6 +207,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
 
tx_desc = >desc[tx_index];
addr = le64_to_cpu(tx_desc->addr);
+   mss_hw_csum = le16_to_cpu(tx_desc->tx.mss_hw_csum);
dev_info(dev, "TX Queue Num: %u, BD Index: %u\n", q_num, tx_index);
dev_info(dev, "(TX)addr: %pad\n", );
dev_info(dev, "(TX)vlan_tag: %u\n", le16_to_cpu(tx_desc->tx.vlan_tag));
@@ -225,7 +227,7 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const 
char *cmd_buf)
dev_info(dev, "(TX)paylen: %u\n", le32_to_cpu(tx_desc->tx.paylen));
dev_info(dev, "(TX)vld_ra_ri: %u\n",
 le16_to_cpu(tx_desc->tx.bdtp_fe_sc_vld_ra_ri));
-   dev_info(dev, "(TX)mss: %u\n", le16_to_cpu(tx_desc->tx.mss));
+   dev_info(dev, "(TX)mss_hw_csum: %u\n", mss_hw_csum);
 
ring = >ring[q_num + h->kinfo.num_tqps];
value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_TAIL_REG);
@@ -324,6 +326,8 @@ static void hns3_dbg_dev_caps(struct hnae3_handle *h)
 test_bit(HNAE3_DEV_SUPPORT_PTP_B, caps) ? "yes" : "no");
dev_info(>pdev->dev, "support INT QL: %s\n",
 test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no");
+   dev_info(>pdev->dev, "support HW TX csum: %s\n",
+test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, caps) ? "yes" : "no");
 }
 
 static void hns3_dbg_dev_specs(struct hnae3_handle *h)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 5a706a3..e022bea 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1055,15 +1055,31 @@ 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 f

[PATCH net-next 7/7] net: hns3: keep MAC pause mode when multiple TCs are enabled

2020-11-27 Thread Huazhong Tan
From: Yonglong Liu 

Bellow HNAE3_DEVICE_VERSION_V3, MAC pause mode just support one
TC, when enabled multiple TCs, force enable PFC mode.

HNAE3_DEVICE_VERSION_V3 can support MAC pause mode on multiple
TCs, so when enable multiple TCs, just keep MAC pause mode,
and enable PFC mode just according to the user settings.

Signed-off-by: Yonglong Liu 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 23 +-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 54767b0..b1026cd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -715,7 +715,7 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
}
 }
 
-static void hclge_pfc_info_init(struct hclge_dev *hdev)
+static void hclge_update_fc_mode_by_dcb_flag(struct hclge_dev *hdev)
 {
if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) {
if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
@@ -733,6 +733,27 @@ static void hclge_pfc_info_init(struct hclge_dev *hdev)
}
 }
 
+static void hclge_update_fc_mode(struct hclge_dev *hdev)
+{
+   if (!hdev->tm_info.pfc_en) {
+   hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
+   return;
+   }
+
+   if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hdev->tm_info.fc_mode = HCLGE_FC_PFC;
+   }
+}
+
+static void hclge_pfc_info_init(struct hclge_dev *hdev)
+{
+   if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+   hclge_update_fc_mode(hdev);
+   else
+   hclge_update_fc_mode_by_dcb_flag(hdev);
+}
+
 static void hclge_tm_schd_info_init(struct hclge_dev *hdev)
 {
hclge_tm_pg_info_init(hdev);
-- 
2.7.4



[PATCH net-next 6/7] net: hns3: add a check for devcie's verion in hns3_tunnel_csum_bug()

2020-11-27 Thread Huazhong Tan
For the device whose version is above V3(include V3), the hardware
can do checksum offload for the non-tunnel udp packet, who has
a dest port as the IANA assigned. So add a check for devcie's verion
in hns3_tunnel_csum_bug().

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 07bdb3d5..b51bf61 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -828,8 +828,16 @@ static int hns3_get_l4_protocol(struct sk_buff *skb, u8 
*ol4_proto,
  */
 static bool hns3_tunnel_csum_bug(struct sk_buff *skb)
 {
+   struct hns3_nic_priv *priv = netdev_priv(skb->dev);
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
union l4_hdr_info l4;
 
+   /* device version above V3(include V3), the hardware can
+* do this checksum offload.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
+   return false;
+
l4.hdr = skb_transport_header(skb);
 
if (!(!skb->encapsulation &&
-- 
2.7.4



[PATCH net-next 0/7] net: hns3: updates for -next

2020-11-27 Thread Huazhong Tan
This series includes some updates for the HNS3 ethernet driver.

#1~#6: add some updates related to the checksum offload.
#7: add support for multiple TCs' MAC pauce mode.

Huazhong Tan (6):
  net: hns3: add support for RX completion checksum
  net: hns3: add support for TX hardware checksum offload
  net: hns3: remove unsupported NETIF_F_GSO_UDP_TUNNEL_CSUM
  net: hns3: add udp tunnel checksum segmentation support
  net: hns3: add more info to hns3_dbg_bd_info()
  net: hns3: add a check for devcie's verion in hns3_tunnel_csum_bug()

Yonglong Liu (1):
  net: hns3: keep MAC pause mode when multiple TCs are enabled

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|   7 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  62 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 131 -
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  21 +++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |   1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |   4 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   3 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  23 +++-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |   4 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |   3 +-
 10 files changed, 207 insertions(+), 52 deletions(-)

-- 
2.7.4



[PATCH net-next 1/7] net: hns3: add support for RX completion checksum

2020-11-27 Thread Huazhong Tan
In some cases (for example ip fragment), hardware will
calculate the checksum of whole packet in RX, and setup
the HNS3_RXD_L2_CSUM_B flag in the descriptor, so add
support to utilize this checksum.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 21 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  7 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  1 +
 3 files changed, 29 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 632ad42..5a706a3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2798,6 +2798,22 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 
l234info)
return 0;
 }
 
+static void hns3_checksum_complete(struct hns3_enet_ring *ring,
+  struct sk_buff *skb, u32 l234info)
+{
+   __sum16 csum;
+
+   u64_stats_update_begin(>syncp);
+   ring->stats.csum_complete++;
+   u64_stats_update_end(>syncp);
+   skb->ip_summed = CHECKSUM_COMPLETE;
+   csum = hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_L_M,
+  HNS3_RXD_L2_CSUM_L_S);
+   csum |= hnae3_get_field(l234info, HNS3_RXD_L2_CSUM_H_M,
+   HNS3_RXD_L2_CSUM_H_S) << 8;
+   skb->csum = csum_unfold(csum);
+}
+
 static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
 u32 l234info, u32 bd_base_info, u32 ol_info)
 {
@@ -2812,6 +2828,11 @@ static void hns3_rx_checksum(struct hns3_enet_ring 
*ring, struct sk_buff *skb,
if (!(netdev->features & NETIF_F_RXCSUM))
return;
 
+   if (l234info & BIT(HNS3_RXD_L2_CSUM_B)) {
+   hns3_checksum_complete(ring, skb, l234info);
+   return;
+   }
+
/* check if hardware has done checksum */
if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
return;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 8d33652..40681a0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -82,6 +82,12 @@ enum hns3_nic_state {
 #define HNS3_RXD_STRP_TAGP_S   13
 #define HNS3_RXD_STRP_TAGP_M   (0x3 << HNS3_RXD_STRP_TAGP_S)
 
+#define HNS3_RXD_L2_CSUM_B 15
+#define HNS3_RXD_L2_CSUM_L_S   4
+#define HNS3_RXD_L2_CSUM_L_M   (0xff << HNS3_RXD_L2_CSUM_L_S)
+#define HNS3_RXD_L2_CSUM_H_S   24
+#define HNS3_RXD_L2_CSUM_H_M   (0xff << HNS3_RXD_L2_CSUM_H_S)
+
 #define HNS3_RXD_L2E_B 16
 #define HNS3_RXD_L3E_B 17
 #define HNS3_RXD_L4E_B 18
@@ -371,6 +377,7 @@ struct ring_stats {
u64 err_bd_num;
u64 l2_err;
u64 l3l4_csum_err;
+   u64 csum_complete;
u64 rx_multicast;
u64 non_reuse_pg;
};
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index c30d5d3..3cca3c1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -55,6 +55,7 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("err_bd_num", err_bd_num),
HNS3_TQP_STAT("l2_err", l2_err),
HNS3_TQP_STAT("l3l4_csum_err", l3l4_csum_err),
+   HNS3_TQP_STAT("csum_complete", csum_complete),
HNS3_TQP_STAT("multicast", rx_multicast),
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
-- 
2.7.4



[PATCH net-next 1/5] net: hns3: add support for 1280 queues

2020-11-20 Thread Huazhong Tan
From: Yonglong Liu 

For DEVICE_VERSION_V1/2, there are total 1024 queues and
queue sets. For DEVICE_VERSION_V3, it increases to 1280,
and can be assigned to one pf, so remove the limitation
of 1024.

To keep compatible with DEVICE_VERSION_V1/2 and old driver
version, the queue number is split into two part:
tqp_num(range 0~1023) and ext_tqp_num(range 1024~1279).

Signed-off-by: Yonglong Liu 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  7 ++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 30 +++---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 29 -
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 37 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  | 11 +++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  3 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 16 --
 7 files changed, 111 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 5b7967c..f458d32 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -307,6 +307,9 @@ enum hclge_opcode_type {
 #define HCLGE_TQP_REG_OFFSET   0x8
 #define HCLGE_TQP_REG_SIZE 0x200
 
+#define HCLGE_TQP_MAX_SIZE_DEV_V2  1024
+#define HCLGE_TQP_EXT_REG_OFFSET   0x100
+
 #define HCLGE_RCB_INIT_QUERY_TIMEOUT   10
 #define HCLGE_RCB_INIT_FLAG_EN_B   0
 #define HCLGE_RCB_INIT_FLAG_FINI_B 8
@@ -479,7 +482,8 @@ struct hclge_pf_res_cmd {
__le16 pf_own_fun_number;
__le16 tx_buf_size;
__le16 dv_buf_size;
-   __le32 rsv[2];
+   __le16 ext_tqp_num;
+   u8 rsv[6];
 };
 
 #define HCLGE_CFG_OFFSET_S 0
@@ -643,7 +647,6 @@ struct hclge_config_mac_speed_dup_cmd {
u8 rsv[22];
 };
 
-#define HCLGE_RING_ID_MASK GENMASK(9, 0)
 #define HCLGE_TQP_ENABLE_B 0
 
 #define HCLGE_MAC_CFG_AN_EN_B  0
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
index 16df050..c82d2ca 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
@@ -681,14 +681,17 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev,
 {
struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd;
struct hclge_nq_to_qs_link_cmd *nq_to_qs_map;
+   u32 qset_mapping[HCLGE_BP_EXT_GRP_NUM];
struct hclge_qs_to_pri_link_cmd *map;
struct hclge_tqp_tx_queue_tc_cmd *tc;
enum hclge_opcode_type cmd;
struct hclge_desc desc;
int queue_id, group_id;
-   u32 qset_mapping[32];
int tc_id, qset_id;
int pri_id, ret;
+   u16 qs_id_l;
+   u16 qs_id_h;
+   u8 grp_num;
u32 i;
 
ret = kstrtouint(cmd_buf, 0, _id);
@@ -701,7 +704,24 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev,
ret = hclge_cmd_send(>hw, , 1);
if (ret)
goto err_tm_map_cmd_send;
-   qset_id = le16_to_cpu(nq_to_qs_map->qset_id) & 0x3FF;
+   qset_id = le16_to_cpu(nq_to_qs_map->qset_id);
+
+   /* convert qset_id to the following format, drop the vld bit
+*| qs_id_h | vld | qs_id_l |
+* qset_id:   | 15 ~ 11 |  10 |  9 ~ 0  |
+* \ \   / /
+*  \ \ / /
+* qset_id: | 15 | 14 ~ 10 |  9 ~ 0  |
+*/
+   qs_id_l = hnae3_get_field(qset_id, HCLGE_TM_QS_ID_L_MSK,
+ HCLGE_TM_QS_ID_L_S);
+   qs_id_h = hnae3_get_field(qset_id, HCLGE_TM_QS_ID_H_EXT_MSK,
+ HCLGE_TM_QS_ID_H_EXT_S);
+   qset_id = 0;
+   hnae3_set_field(qset_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S,
+   qs_id_l);
+   hnae3_set_field(qset_id, HCLGE_TM_QS_ID_H_MSK, HCLGE_TM_QS_ID_H_S,
+   qs_id_h);
 
cmd = HCLGE_OPC_TM_QS_TO_PRI_LINK;
map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
@@ -731,9 +751,11 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev,
return;
}
 
+   grp_num = hdev->num_tqps <= HCLGE_TQP_MAX_SIZE_DEV_V2 ?
+ HCLGE_BP_GRP_NUM : HCLGE_BP_EXT_GRP_NUM;
cmd = HCLGE_OPC_TM_BP_TO_QSET_MAPPING;
bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
-   for (group_id = 0; group_id < 32; group_id++) {
+   for (group_id = 0; group_id < grp_num; group_id++) {
hclge_cmd_setup_basic_desc(, cmd, true);
bp_to_qs_map_cmd->tc_id = tc_id;
bp_to_qs_map_cmd->qs_group_id = group_id;
@@ -748,7 +770,7 @@ static void hclge_dbg_dump_tm_map(struct hclge_dev *hdev,
dev_info(>pde

[PATCH net-next 4/5] net: hns3: add support to utilize the firmware calculated shaping parameters

2020-11-20 Thread Huazhong Tan
From: Yonglong Liu 

Since the calculation of the driver is fixed, if the number of
queue or clock changed, the calculated result may be inaccurate.

So for compatible and maintainable, add a new flag to tell the
firmware to calculate the shaping parameters with the specified
rate.

Signed-off-by: Yonglong Liu 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 43 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  | 15 
 2 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index b50b079..54767b0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -395,7 +395,7 @@ static u32 hclge_tm_get_shapping_para(u8 ir_b, u8 ir_u, u8 
ir_s,
 
 static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
enum hclge_shap_bucket bucket, u8 pg_id,
-   u32 shapping_para)
+   u32 shapping_para, u32 rate)
 {
struct hclge_pg_shapping_cmd *shap_cfg_cmd;
enum hclge_opcode_type opcode;
@@ -411,6 +411,10 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
 
shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para);
 
+   hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
+
+   shap_cfg_cmd->pg_rate = cpu_to_le32(rate);
+
return hclge_cmd_send(>hw, , 1);
 }
 
@@ -438,12 +442,16 @@ static int hclge_tm_port_shaper_cfg(struct hclge_dev 
*hdev)
 
shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para);
 
+   hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
+
+   shap_cfg_cmd->port_rate = cpu_to_le32(hdev->hw.mac.speed);
+
return hclge_cmd_send(>hw, , 1);
 }
 
 static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
 enum hclge_shap_bucket bucket, u8 pri_id,
-u32 shapping_para)
+u32 shapping_para, u32 rate)
 {
struct hclge_pri_shapping_cmd *shap_cfg_cmd;
enum hclge_opcode_type opcode;
@@ -460,6 +468,10 @@ static int hclge_tm_pri_shapping_cfg(struct hclge_dev 
*hdev,
 
shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para);
 
+   hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
+
+   shap_cfg_cmd->pri_rate = cpu_to_le32(rate);
+
return hclge_cmd_send(>hw, , 1);
 }
 
@@ -561,6 +573,9 @@ int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int 
max_tx_rate)
shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i);
shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para);
 
+   hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
+   shap_cfg_cmd->qs_rate = cpu_to_le32(max_tx_rate);
+
ret = hclge_cmd_send(>hw, , 1);
if (ret) {
dev_err(>pdev->dev,
@@ -762,9 +777,10 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev)
 
/* Pg to pri */
for (i = 0; i < hdev->tm_info.num_pg; i++) {
+   u32 rate = hdev->tm_info.pg_info[i].bw_limit;
+
/* Calc shaper para */
-   ret = hclge_shaper_para_calc(hdev->tm_info.pg_info[i].bw_limit,
-HCLGE_SHAPER_LVL_PG,
+   ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PG,
 _para, max_tm_rate);
if (ret)
return ret;
@@ -774,7 +790,7 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev)
 HCLGE_SHAPER_BS_S_DEF);
ret = hclge_tm_pg_shapping_cfg(hdev,
   HCLGE_TM_SHAP_C_BUCKET, i,
-  shaper_para);
+  shaper_para, rate);
if (ret)
return ret;
 
@@ -785,7 +801,7 @@ static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev)
 HCLGE_SHAPER_BS_S_DEF);
ret = hclge_tm_pg_shapping_cfg(hdev,
   HCLGE_TM_SHAP_P_BUCKET, i,
-  shaper_para);
+  shaper_para, rate);
if (ret)
return ret;
}
@@ -891,8 +907,9 @@ static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev 
*hdev)
u32 i;
 
for (i = 0; i < hdev->tm_info.num_tc; i++) {
-   ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit,
- 

[PATCH net-next 0/5] net: hns3: misc updates for -next

2020-11-20 Thread Huazhong Tan
This series includes some misc updates for the HNS3 ethernet driver.

#1 adds support for 1280 queues
#2 adds mapping for BAR45 which is needed by RoCE client.
#3 extend the interrupt resources.
#4 add support to query firmware's calculated shaping parameters.

Huazhong Tan (1):
  net: hns3: add support for mapping device memory

Yonglong Liu (3):
  net: hns3: add support for 1280 queues
  net: hns3: add support to utilize the firmware calculated shaping
parameters
  net: hns3: adds debugfs to dump more info of shaping parameters

Yufeng Mo (1):
  net: hns3: add support for pf querying new interrupt resources

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|   1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|   3 -
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  23 +--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c |  48 ++-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 160 ++---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   4 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  80 ---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  26 
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |   3 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  49 ++-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |   1 +
 11 files changed, 310 insertions(+), 88 deletions(-)

-- 
2.7.4



[PATCH net-next 3/5] net: hns3: add support for pf querying new interrupt resources

2020-11-20 Thread Huazhong Tan
From: Yufeng Mo 

For HNAE3_DEVICE_VERSION_V3, a maximum of 1281 interrupt
resources are supported. To utilize these new resources,
extend the corresponding field or variable to 16bit type,
and remove the restriction of NIC client that only use a
maximum of 65 interrupt vectors. In addition, the I/O address
of the extended interrupt resources are different, so an extra
handler is needed.

Currently, the total number of interrupts is the sum of RoCE's
number and RoCE's offset (RoCE is in front of NIC), since
the number of both NIC and RoCE are same. For readability,
rewrite the corresponding field of the command, rename the
RoCE's offset field as the number of NIC interrupts, then
the total number of interrupts is sum of the number of RoCE
and NIC, and replace vport->back with hdev in
hclge_init_roce_base_info() for simplifying the code.

Signed-off-by: Yufeng Mo 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|   3 -
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  16 ++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 100 -
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   3 +-
 4 files changed, 69 insertions(+), 53 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 999a2aa..632ad42 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3645,8 +3645,6 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv 
*priv)
 
 static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
 {
-#define HNS3_VECTOR_PF_MAX_NUM 64
-
struct hnae3_handle *h = priv->ae_handle;
struct hns3_enet_tqp_vector *tqp_vector;
struct hnae3_vector_info *vector;
@@ -3659,7 +3657,6 @@ static int hns3_nic_alloc_vector_data(struct 
hns3_nic_priv *priv)
/* RSS size, cpu online and vector_num should be the same */
/* Should consider 2p/4p later */
vector_num = min_t(u16, num_online_cpus(), tqp_num);
-   vector_num = min_t(u16, vector_num, HNS3_VECTOR_PF_MAX_NUM);
 
vector = devm_kcalloc(>dev, vector_num, sizeof(*vector),
  GFP_KERNEL);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index f458d32..6d7ba20 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -339,7 +339,9 @@ enum hclge_int_type {
 };
 
 struct hclge_ctrl_vector_chain_cmd {
-   u8 int_vector_id;
+#define HCLGE_VECTOR_ID_L_S0
+#define HCLGE_VECTOR_ID_L_MGENMASK(7, 0)
+   u8 int_vector_id_l;
u8 int_cause_num;
 #define HCLGE_INT_TYPE_S   0
 #define HCLGE_INT_TYPE_M   GENMASK(1, 0)
@@ -349,7 +351,9 @@ struct hclge_ctrl_vector_chain_cmd {
 #define HCLGE_INT_GL_IDX_M GENMASK(14, 13)
__le16 tqp_type_and_id[HCLGE_VECTOR_ELEMENTS_PER_CMD];
u8 vfid;
-   u8 rsv;
+#define HCLGE_VECTOR_ID_H_S8
+#define HCLGE_VECTOR_ID_H_MGENMASK(15, 8)
+   u8 int_vector_id_h;
 };
 
 #define HCLGE_MAX_TC_NUM   8
@@ -473,12 +477,8 @@ struct hclge_pf_res_cmd {
__le16 tqp_num;
__le16 buf_size;
__le16 msixcap_localid_ba_nic;
-   __le16 msixcap_localid_ba_rocee;
-#define HCLGE_MSIX_OFT_ROCEE_S 0
-#define HCLGE_MSIX_OFT_ROCEE_M GENMASK(15, 0)
-#define HCLGE_PF_VEC_NUM_S 0
-#define HCLGE_PF_VEC_NUM_M GENMASK(7, 0)
-   __le16 pf_intr_vector_number;
+   __le16 msixcap_localid_number_nic;
+   __le16 pf_intr_vector_number_roce;
__le16 pf_own_fun_number;
__le16 tx_buf_size;
__le16 dv_buf_size;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 9989930..500cc19 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -906,35 +906,24 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev)
 
hdev->dv_buf_size = roundup(hdev->dv_buf_size, HCLGE_BUF_SIZE_UNIT);
 
+   hdev->num_nic_msi = le16_to_cpu(req->msixcap_localid_number_nic);
+   if (hdev->num_nic_msi < HNAE3_MIN_VECTOR_NUM) {
+   dev_err(>pdev->dev,
+   "only %u msi resources available, not enough for 
pf(min:2).\n",
+   hdev->num_nic_msi);
+   return -EINVAL;
+   }
+
if (hnae3_dev_roce_supported(hdev)) {
-   hdev->roce_base_msix_offset =
-   hnae3_get_field(le16_to_cpu(req->msixcap_localid_ba_rocee),
-   HCLGE_MSIX_OFT_ROCEE_M, HCLGE_MSIX_OFT_ROCEE_S);
hdev->num_roce_msi =
-  

[PATCH net-next 2/5] net: hns3: add support for mapping device memory

2020-11-20 Thread Huazhong Tan
For device who has device memory accessed through the PCI BAR4,
IO descriptor push of NIC and direct WQE(Work Queue Element) of
RoCE will use this device memory, so add support for mapping
this device memory, and add this info to the RoCE client whose
new feature needs.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 33 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 33 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |  1 +
 5 files changed, 69 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f9d4d23..5bae5e8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -689,6 +689,7 @@ struct hnae3_knic_private_info {
 struct hnae3_roce_private_info {
struct net_device *netdev;
void __iomem *roce_io_base;
+   void __iomem *roce_mem_base;
int base_vector;
int num_vectors;
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 892e7f6..9989930 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2436,6 +2436,7 @@ static int hclge_init_roce_base_info(struct hclge_vport 
*vport)
 
roce->rinfo.netdev = nic->kinfo.netdev;
roce->rinfo.roce_io_base = vport->back->hw.io_base;
+   roce->rinfo.roce_mem_base = vport->back->hw.mem_base;
 
roce->pdev = nic->pdev;
roce->ae_algo = nic->ae_algo;
@@ -9890,6 +9891,28 @@ static void hclge_uninit_client_instance(struct 
hnae3_client *client,
}
 }
 
+static int hclge_dev_mem_map(struct hclge_dev *hdev)
+{
+#define HCLGE_MEM_BAR  4
+
+   struct pci_dev *pdev = hdev->pdev;
+   struct hclge_hw *hw = >hw;
+
+   /* for device does not have device memory, return directly */
+   if (!(pci_select_bars(pdev, IORESOURCE_MEM) & BIT(HCLGE_MEM_BAR)))
+   return 0;
+
+   hw->mem_base = devm_ioremap_wc(>dev,
+  pci_resource_start(pdev, HCLGE_MEM_BAR),
+  pci_resource_len(pdev, HCLGE_MEM_BAR));
+   if (!hw->mem_base) {
+   dev_err(>dev, "failed to map device memroy\n");
+   return -EFAULT;
+   }
+
+   return 0;
+}
+
 static int hclge_pci_init(struct hclge_dev *hdev)
 {
struct pci_dev *pdev = hdev->pdev;
@@ -9928,9 +9951,16 @@ static int hclge_pci_init(struct hclge_dev *hdev)
goto err_clr_master;
}
 
+   ret = hclge_dev_mem_map(hdev);
+   if (ret)
+   goto err_unmap_io_base;
+
hdev->num_req_vfs = pci_sriov_get_totalvfs(pdev);
 
return 0;
+
+err_unmap_io_base:
+   pcim_iounmap(pdev, hdev->hw.io_base);
 err_clr_master:
pci_clear_master(pdev);
pci_release_regions(pdev);
@@ -9944,6 +9974,9 @@ static void hclge_pci_uninit(struct hclge_dev *hdev)
 {
struct pci_dev *pdev = hdev->pdev;
 
+   if (hdev->hw.mem_base)
+   devm_iounmap(>dev, hdev->hw.mem_base);
+
pcim_iounmap(pdev, hdev->hw.io_base);
pci_free_irq_vectors(pdev);
pci_clear_master(pdev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 64e6afd..3ed4e84 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -278,6 +278,7 @@ struct hclge_mac {
 
 struct hclge_hw {
void __iomem *io_base;
+   void __iomem *mem_base;
struct hclge_mac mac;
int num_vec;
struct hclge_cmq cmq;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 5ac5c35..5d6b419 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -2442,6 +2442,7 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev 
*hdev)
 
roce->rinfo.netdev = nic->kinfo.netdev;
roce->rinfo.roce_io_base = hdev->hw.io_base;
+   roce->rinfo.roce_mem_base = hdev->hw.mem_base;
 
roce->pdev = nic->pdev;
roce->ae_algo = nic->ae_algo;
@@ -2887,6 +2888,29 @@ static void hclgevf_uninit_client_instance(struct 
hnae3_client *client,
}
 }
 
+static int hclgevf_dev_mem_map(struct hclgevf_dev *hdev)
+{
+#define HCLGEVF_MEM_BAR4
+
+   struct pci_dev *pdev = hdev->pdev;
+   struct hclgevf_hw *hw = >hw;
+
+   /* for 

[PATCH net-next 5/5] net: hns3: adds debugfs to dump more info of shaping parameters

2020-11-20 Thread Huazhong Tan
From: Yonglong Liu 

Adds debugfs to dump new shaping parameters: rate and flag.

Signed-off-by: Yonglong Liu 
Signed-off-by: Huazhong Tan 
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
index c82d2ca..bedbc11 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
@@ -498,6 +498,9 @@ static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev)
dev_info(>pdev->dev, "PG_P pg_id: %u\n", pg_shap_cfg_cmd->pg_id);
dev_info(>pdev->dev, "PG_P pg_shapping: 0x%x\n",
 le32_to_cpu(pg_shap_cfg_cmd->pg_shapping_para));
+   dev_info(>pdev->dev, "PG_P flag: %#x\n", pg_shap_cfg_cmd->flag);
+   dev_info(>pdev->dev, "PG_P pg_rate: %u(Mbps)\n",
+le32_to_cpu(pg_shap_cfg_cmd->pg_rate));
 
cmd = HCLGE_OPC_TM_PORT_SHAPPING;
hclge_cmd_setup_basic_desc(, cmd, true);
@@ -508,6 +511,9 @@ static void hclge_dbg_dump_tm_pg(struct hclge_dev *hdev)
port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
dev_info(>pdev->dev, "PORT port_shapping: 0x%x\n",
 le32_to_cpu(port_shap_cfg_cmd->port_shapping_para));
+   dev_info(>pdev->dev, "PORT flag: %#x\n", port_shap_cfg_cmd->flag);
+   dev_info(>pdev->dev, "PORT port_rate: %u(Mbps)\n",
+le32_to_cpu(port_shap_cfg_cmd->port_rate));
 
cmd = HCLGE_OPC_TM_PG_SCH_MODE_CFG;
hclge_cmd_setup_basic_desc(, cmd, true);
@@ -655,6 +661,9 @@ static void hclge_dbg_dump_tm(struct hclge_dev *hdev)
dev_info(>pdev->dev, "PRI_C pri_id: %u\n", shap_cfg_cmd->pri_id);
dev_info(>pdev->dev, "PRI_C pri_shapping: 0x%x\n",
 le32_to_cpu(shap_cfg_cmd->pri_shapping_para));
+   dev_info(>pdev->dev, "PRI_C flag: %#x\n", shap_cfg_cmd->flag);
+   dev_info(>pdev->dev, "PRI_C pri_rate: %u(Mbps)\n",
+le32_to_cpu(shap_cfg_cmd->pri_rate));
 
cmd = HCLGE_OPC_TM_PRI_P_SHAPPING;
hclge_cmd_setup_basic_desc(, cmd, true);
@@ -666,6 +675,9 @@ static void hclge_dbg_dump_tm(struct hclge_dev *hdev)
dev_info(>pdev->dev, "PRI_P pri_id: %u\n", shap_cfg_cmd->pri_id);
dev_info(>pdev->dev, "PRI_P pri_shapping: 0x%x\n",
 le32_to_cpu(shap_cfg_cmd->pri_shapping_para));
+   dev_info(>pdev->dev, "PRI_P flag: %#x\n", shap_cfg_cmd->flag);
+   dev_info(>pdev->dev, "PRI_P pri_rate: %u(Mbps)\n",
+le32_to_cpu(shap_cfg_cmd->pri_rate));
 
hclge_dbg_dump_tm_pg(hdev);
 
@@ -1401,6 +1413,7 @@ static void hclge_dbg_dump_qs_shaper_single(struct 
hclge_dev *hdev, u16 qsid)
u8 ir_u, ir_b, ir_s, bs_b, bs_s;
struct hclge_desc desc;
u32 shapping_para;
+   u32 rate;
int ret;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_QCN_SHAPPING_CFG, true);
@@ -1422,10 +1435,11 @@ static void hclge_dbg_dump_qs_shaper_single(struct 
hclge_dev *hdev, u16 qsid)
ir_s = hclge_tm_get_field(shapping_para, IR_S);
bs_b = hclge_tm_get_field(shapping_para, BS_B);
bs_s = hclge_tm_get_field(shapping_para, BS_S);
+   rate = le32_to_cpu(shap_cfg_cmd->qs_rate);
 
dev_info(>pdev->dev,
-"qs%u ir_b:%u, ir_u:%u, ir_s:%u, bs_b:%u, bs_s:%u\n",
-qsid, ir_b, ir_u, ir_s, bs_b, bs_s);
+"qs%u ir_b:%u, ir_u:%u, ir_s:%u, bs_b:%u, bs_s:%u, flag:%#x, 
rate:%u(Mbps)\n",
+qsid, ir_b, ir_u, ir_s, bs_b, bs_s, shap_cfg_cmd->flag, rate);
 }
 
 static void hclge_dbg_dump_qs_shaper_all(struct hclge_dev *hdev)
-- 
2.7.4



[RFC V2 net-next 1/2] ethtool: add support for controling the type of adaptive coalescing

2020-11-19 Thread Huazhong Tan
Since the information whether the adaptive behavior is implemented
by DIM or driver custom is useful, so add new attribute to
ETHTOOL_MSG_COALESCE_GET/ETHTOOL_MSG_COALESCE_SET commands to control
the type of adaptive coalescing.

In order to compatible with ioctl code, add a extended coalescing
handler to deal with it in the netlink API, then other new extended
coalescing parameters can utiliaze it as well.

Suggested-by: Jakub Kicinski 
Signed-off-by: Huazhong Tan 
---
 Documentation/networking/ethtool-netlink.rst |  1 +
 include/linux/ethtool.h  | 14 +++
 include/uapi/linux/ethtool_netlink.h |  1 +
 net/ethtool/coalesce.c   | 35 ++--
 net/ethtool/netlink.h|  2 +-
 5 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/Documentation/networking/ethtool-netlink.rst 
b/Documentation/networking/ethtool-netlink.rst
index 30b9824..dae7145 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -928,6 +928,7 @@ Kernel response contents:
   ``ETHTOOL_A_COALESCE_TX_USECS_HIGH`` u32 delay (us), high Tx
   ``ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH``u32 max packets, high Tx
   ``ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL``  u32 rate sampling interval
+  ``ETHTOOL_A_COALESCE_USE_DIM``   boolusing DIM adaptive
   ===  ==  ===
 
 Attributes are only included in reply if their value is not zero or the
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 6408b44..4426d65 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -215,6 +215,7 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 
*legacy_u32,
 #define ETHTOOL_COALESCE_TX_USECS_HIGH BIT(19)
 #define ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGHBIT(20)
 #define ETHTOOL_COALESCE_RATE_SAMPLE_INTERVAL  BIT(21)
+#define ETHTOOL_COALESCE_USE_DIM   BIT(22)
 
 #define ETHTOOL_COALESCE_USECS \
(ETHTOOL_COALESCE_RX_USECS | ETHTOOL_COALESCE_TX_USECS)
@@ -241,6 +242,10 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 
*legacy_u32,
 ETHTOOL_COALESCE_PKT_RATE_LOW | ETHTOOL_COALESCE_PKT_RATE_HIGH | \
 ETHTOOL_COALESCE_RATE_SAMPLE_INTERVAL)
 
+struct ethtool_ext_coalesce {
+   __u32 use_dim;
+};
+
 #define ETHTOOL_STAT_NOT_SET   (~0ULL)
 
 /**
@@ -298,9 +303,14 @@ struct ethtool_pause_stats {
  * or zero.
  * @get_coalesce: Get interrupt coalescing parameters.  Returns a negative
  * error code or zero.
+ * @get_ext_coalesce: Get extended interrupt coalescing parameters.
+ * Returns a negative error code or zero.
  * @set_coalesce: Set interrupt coalescing parameters.  Supported coalescing
  * types should be set in @supported_coalesce_params.
  * Returns a negative error code or zero.
+ * @set_ext_coalesce: Set extended interrupt coalescing parameters.  Supported
+ * extended coalescing types should be set in @supported_coalesce_params.
+ * Returns a negative error code or zero.
  * @get_ringparam: Report ring sizes
  * @set_ringparam: Set ring sizes.  Returns a negative error code or zero.
  * @get_pause_stats: Report pause frame statistics. Drivers must not zero
@@ -437,7 +447,11 @@ struct ethtool_ops {
int (*set_eeprom)(struct net_device *,
  struct ethtool_eeprom *, u8 *);
int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *);
+   int (*get_ext_coalesce)(struct net_device *,
+   struct ethtool_ext_coalesce *);
int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *);
+   int (*set_ext_coalesce)(struct net_device *,
+   struct ethtool_ext_coalesce *);
void(*get_ringparam)(struct net_device *,
 struct ethtool_ringparam *);
int (*set_ringparam)(struct net_device *,
diff --git a/include/uapi/linux/ethtool_netlink.h 
b/include/uapi/linux/ethtool_netlink.h
index e2bf36e..e3458d9 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -366,6 +366,7 @@ enum {
ETHTOOL_A_COALESCE_TX_USECS_HIGH,   /* u32 */
ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH,  /* u32 */
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,/* u32 */
+   ETHTOOL_A_COALESCE_USE_DIM, /* u8 */
 
/* add new constants above here */
__ETHTOOL_A_COALESCE_CNT,
diff --git a/net/ethtool/coalesce.c b/net/ethtool/coalesce.c
index 1d6bc13..d4d8901 100644
--- a/net/ethtool/coalesce.c
+++ b/net/ethtool/coalesce.c
@@ -11,6 +11,7 @@ struct coalesce_reply_data {
struct ethnl_reply_data base;
struct ethtool_coalesce coalesce;
u32

[RFC V2 net-next 2/2] net: hns3: add support for dynamic interrupt moderation

2020-11-19 Thread Huazhong Tan
Add dynamic interrupt moderation support for the HNS3 driver,
and add ethtool support for controlling the type of adaptive.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/Kconfig |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 87 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  4 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 25 ++-
 4 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 44f9279..fa6025d 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -130,6 +130,7 @@ config HNS3_ENET
default m
depends on 64BIT && PCI
depends on INET
+   select DIMLIB
help
  This selects the Ethernet Driver for Hisilicon Network Subsystem 3 
for hip08
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 999a2aa..b08aea7 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -96,6 +96,7 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
struct hns3_enet_tqp_vector *tqp_vector = vector;
 
napi_schedule_irqoff(_vector->napi);
+   tqp_vector->event_cnt++;
 
return IRQ_HANDLED;
 }
@@ -199,6 +200,8 @@ static void hns3_vector_disable(struct hns3_enet_tqp_vector 
*tqp_vector)
 
disable_irq(tqp_vector->vector_irq);
napi_disable(_vector->napi);
+   cancel_work_sync(_vector->rx_group.dim.work);
+   cancel_work_sync(_vector->tx_group.dim.work);
 }
 
 void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
@@ -3401,6 +3404,32 @@ static void hns3_update_new_int_gl(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->last_jiffies = jiffies;
 }
 
+static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *rx_group = _vector->rx_group;
+   struct dim_sample sample = {};
+
+   if (!rx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, rx_group->total_packets,
+ rx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
+static void hns3_update_tx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *tx_group = _vector->tx_group;
+   struct dim_sample sample = {};
+
+   if (!tx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, tx_group->total_packets,
+ tx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
 static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
 {
struct hns3_nic_priv *priv = netdev_priv(napi->dev);
@@ -3444,7 +3473,13 @@ static int hns3_nic_common_poll(struct napi_struct 
*napi, int budget)
 
if (napi_complete(napi) &&
likely(!test_bit(HNS3_NIC_STATE_DOWN, >state))) {
-   hns3_update_new_int_gl(tqp_vector);
+   if (priv->dim_enable) {
+   hns3_update_rx_int_coalesce(tqp_vector);
+   hns3_update_tx_int_coalesce(tqp_vector);
+   } else {
+   hns3_update_new_int_gl(tqp_vector);
+   }
+
hns3_mask_vector_irq(tqp_vector, 1);
}
 
@@ -3575,6 +3610,54 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv 
*priv)
}
 }
 
+static void hns3_rx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+
+   hns3_set_vector_coalesce_rx_gl(group->ring->tqp_vector, cur_moder.usec);
+   tqp_vector->rx_group.coal.int_gl = cur_moder.usec;
+
+   if (cur_moder.pkts < tqp_vector->rx_group.coal.int_ql_max) {
+   hns3_set_vector_coalesce_rx_ql(tqp_vector, cur_moder.pkts);
+   tqp_vector->rx_group.coal.int_ql = cur_moder.pkts;
+   }
+
+   dim->state = DIM_START_MEASURE;
+}
+
+static void hns3_tx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->

[RFC V2 net-next 0/2] net: updates for -next

2020-11-19 Thread Huazhong Tan
#2 will add DIM for the HNS3 ethernet driver, then there will
be two implemation of IRQ adaptive coalescing (DIM and driver
custiom, so #1 adds a new netlink attribute to the
ETHTOOL_MSG_COALESCE_GET/ETHTOOL_MSG_COALESCE_SET commands
which controls the type of adaptive coalescing.

change log:
V2: fixes some problems in #1 reported by Andrew Lunn & Michal Kubecek.

previous version:
V1: 
https://patchwork.ozlabs.org/project/netdev/cover/1605758050-21061-1-git-send-email-tanhuazh...@huawei.com/

Huazhong Tan (2):
  ethtool: add support for controling the type of adaptive coalescing
  net: hns3: add support for dynamic interrupt moderation

 Documentation/networking/ethtool-netlink.rst   |  1 +
 drivers/net/ethernet/hisilicon/Kconfig |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 87 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  4 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 25 ++-
 include/linux/ethtool.h| 14 
 include/uapi/linux/ethtool_netlink.h   |  1 +
 net/ethtool/coalesce.c | 35 -
 net/ethtool/netlink.h  |  2 +-
 9 files changed, 165 insertions(+), 5 deletions(-)

-- 
2.7.4



[RFC net-next 0/2] net: updates for -next

2020-11-18 Thread Huazhong Tan
#2 will add DIM for the HNS3 ethernet driver, then there will
be two implemation of IRQ adaptive coalescing (DIM and driver
custiom, so #1 adds a new netlink attribute to the
ETHTOOL_MSG_COALESCE_GET/ETHTOOL_MSG_COALESCE_SET commands
which controls the type of adaptive coalescing.

Huazhong Tan (2):
  ethtool: add support for controling the type of adaptive coalescing
  net: hns3: add support for dynamic interrupt moderation

 drivers/net/ethernet/hisilicon/Kconfig |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 87 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  4 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  7 +-
 include/linux/ethtool.h|  1 +
 include/uapi/linux/ethtool.h   |  2 +
 include/uapi/linux/ethtool_netlink.h   |  1 +
 net/ethtool/coalesce.c | 11 ++-
 net/ethtool/netlink.h  |  2 +-
 9 files changed, 111 insertions(+), 5 deletions(-)

-- 
2.7.4



[RFC net-next 1/2] ethtool: add support for controling the type of adaptive coalescing

2020-11-18 Thread Huazhong Tan
Since the information whether the adaptive behavior is implemented
by DIM or driver custom is useful, so add new attribute to
ETHTOOL_MSG_COALESCE_GET/ETHTOOL_MSG_COALESCE_SET commands to control
the type of adaptive coalescing.

Suggested-by: Jakub Kicinski 
Signed-off-by: Huazhong Tan 
---
 include/linux/ethtool.h  |  1 +
 include/uapi/linux/ethtool.h |  2 ++
 include/uapi/linux/ethtool_netlink.h |  1 +
 net/ethtool/coalesce.c   | 11 +--
 net/ethtool/netlink.h|  2 +-
 5 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 6408b44..f57cb92 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -215,6 +215,7 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 
*legacy_u32,
 #define ETHTOOL_COALESCE_TX_USECS_HIGH BIT(19)
 #define ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGHBIT(20)
 #define ETHTOOL_COALESCE_RATE_SAMPLE_INTERVAL  BIT(21)
+#define ETHTOOL_COALESCE_USE_DIM   BIT(22)
 
 #define ETHTOOL_COALESCE_USECS \
(ETHTOOL_COALESCE_RX_USECS | ETHTOOL_COALESCE_TX_USECS)
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 9ca87bc..afd8de2 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -433,6 +433,7 @@ struct ethtool_modinfo {
  * a TX interrupt, when the packet rate is above @pkt_rate_high.
  * @rate_sample_interval: How often to do adaptive coalescing packet rate
  * sampling, measured in seconds.  Must not be zero.
+ * @use_dim: Use DIM for IRQ coalescing, if adaptive coalescing is enabled.
  *
  * Each pair of (usecs, max_frames) fields specifies that interrupts
  * should be coalesced until
@@ -483,6 +484,7 @@ struct ethtool_coalesce {
__u32   tx_coalesce_usecs_high;
__u32   tx_max_coalesced_frames_high;
__u32   rate_sample_interval;
+   __u32   use_dim;
 };
 
 /**
diff --git a/include/uapi/linux/ethtool_netlink.h 
b/include/uapi/linux/ethtool_netlink.h
index e2bf36e..e3458d9 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -366,6 +366,7 @@ enum {
ETHTOOL_A_COALESCE_TX_USECS_HIGH,   /* u32 */
ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH,  /* u32 */
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,/* u32 */
+   ETHTOOL_A_COALESCE_USE_DIM, /* u8 */
 
/* add new constants above here */
__ETHTOOL_A_COALESCE_CNT,
diff --git a/net/ethtool/coalesce.c b/net/ethtool/coalesce.c
index 1d6bc13..f12e5de 100644
--- a/net/ethtool/coalesce.c
+++ b/net/ethtool/coalesce.c
@@ -50,6 +50,7 @@ __CHECK_SUPPORTED_OFFSET(COALESCE_RX_MAX_FRAMES_HIGH);
 __CHECK_SUPPORTED_OFFSET(COALESCE_TX_USECS_HIGH);
 __CHECK_SUPPORTED_OFFSET(COALESCE_TX_MAX_FRAMES_HIGH);
 __CHECK_SUPPORTED_OFFSET(COALESCE_RATE_SAMPLE_INTERVAL);
+__CHECK_SUPPORTED_OFFSET(COALESCE_USE_DIM);
 
 const struct nla_policy ethnl_coalesce_get_policy[] = {
[ETHTOOL_A_COALESCE_HEADER] =
@@ -100,7 +101,8 @@ static int coalesce_reply_size(const struct ethnl_req_info 
*req_base,
   nla_total_size(sizeof(u32)) +/* _RX_MAX_FRAMES_HIGH */
   nla_total_size(sizeof(u32)) +/* _TX_USECS_HIGH */
   nla_total_size(sizeof(u32)) +/* _TX_MAX_FRAMES_HIGH */
-  nla_total_size(sizeof(u32)); /* _RATE_SAMPLE_INTERVAL */
+  nla_total_size(sizeof(u32)) +/* _RATE_SAMPLE_INTERVAL */
+  nla_total_size(sizeof(u8));  /* _USE_DIM */
 }
 
 static bool coalesce_put_u32(struct sk_buff *skb, u16 attr_type, u32 val,
@@ -170,7 +172,9 @@ static int coalesce_fill_reply(struct sk_buff *skb,
coalesce_put_u32(skb, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH,
 coal->tx_max_coalesced_frames_high, supported) ||
coalesce_put_u32(skb, ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,
-coal->rate_sample_interval, supported))
+coal->rate_sample_interval, supported) ||
+   coalesce_put_bool(skb, ETHTOOL_A_COALESCE_USE_DIM,
+ coal->use_dim, supported))
return -EMSGSIZE;
 
return 0;
@@ -215,6 +219,7 @@ const struct nla_policy ethnl_coalesce_set_policy[] = {
[ETHTOOL_A_COALESCE_TX_USECS_HIGH]  = { .type = NLA_U32 },
[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH] = { .type = NLA_U32 },
[ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL] = { .type = NLA_U32 },
+   [ETHTOOL_A_COALESCE_USE_DIM]= { .type = NLA_U8 },
 };
 
 int ethnl_set_coalesce(struct sk_buff *skb, struct genl_info *info)
@@ -303,6 +308,8 @@ int ethnl_set_coalesce(struct sk_buff *skb, struct 
genl_info *info)
 tb[ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH], );
ethnl_update_u32(_sample_interval,
   

[RFC net-next 2/2] net: hns3: add support for dynamic interrupt moderation

2020-11-18 Thread Huazhong Tan
Add dynamic interrupt moderation support for the HNS3 driver,
and add ethtool support for controlling the type of adaptive.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/Kconfig |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 87 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  4 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  7 +-
 4 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 44f9279..fa6025d 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -130,6 +130,7 @@ config HNS3_ENET
default m
depends on 64BIT && PCI
depends on INET
+   select DIMLIB
help
  This selects the Ethernet Driver for Hisilicon Network Subsystem 3 
for hip08
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 999a2aa..b08aea7 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -96,6 +96,7 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
struct hns3_enet_tqp_vector *tqp_vector = vector;
 
napi_schedule_irqoff(_vector->napi);
+   tqp_vector->event_cnt++;
 
return IRQ_HANDLED;
 }
@@ -199,6 +200,8 @@ static void hns3_vector_disable(struct hns3_enet_tqp_vector 
*tqp_vector)
 
disable_irq(tqp_vector->vector_irq);
napi_disable(_vector->napi);
+   cancel_work_sync(_vector->rx_group.dim.work);
+   cancel_work_sync(_vector->tx_group.dim.work);
 }
 
 void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
@@ -3401,6 +3404,32 @@ static void hns3_update_new_int_gl(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->last_jiffies = jiffies;
 }
 
+static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *rx_group = _vector->rx_group;
+   struct dim_sample sample = {};
+
+   if (!rx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, rx_group->total_packets,
+ rx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
+static void hns3_update_tx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *tx_group = _vector->tx_group;
+   struct dim_sample sample = {};
+
+   if (!tx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, tx_group->total_packets,
+ tx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
 static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
 {
struct hns3_nic_priv *priv = netdev_priv(napi->dev);
@@ -3444,7 +3473,13 @@ static int hns3_nic_common_poll(struct napi_struct 
*napi, int budget)
 
if (napi_complete(napi) &&
likely(!test_bit(HNS3_NIC_STATE_DOWN, >state))) {
-   hns3_update_new_int_gl(tqp_vector);
+   if (priv->dim_enable) {
+   hns3_update_rx_int_coalesce(tqp_vector);
+   hns3_update_tx_int_coalesce(tqp_vector);
+   } else {
+   hns3_update_new_int_gl(tqp_vector);
+   }
+
hns3_mask_vector_irq(tqp_vector, 1);
}
 
@@ -3575,6 +3610,54 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv 
*priv)
}
 }
 
+static void hns3_rx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+
+   hns3_set_vector_coalesce_rx_gl(group->ring->tqp_vector, cur_moder.usec);
+   tqp_vector->rx_group.coal.int_gl = cur_moder.usec;
+
+   if (cur_moder.pkts < tqp_vector->rx_group.coal.int_ql_max) {
+   hns3_set_vector_coalesce_rx_ql(tqp_vector, cur_moder.pkts);
+   tqp_vector->rx_group.coal.int_ql = cur_moder.pkts;
+   }
+
+   dim->state = DIM_START_MEASURE;
+}
+
+static void hns3_tx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cu

[PATCH V4 net-next 2/4] net: hns3: add support for querying maximum value of GL

2020-11-16 Thread Huazhong Tan
For maintainability and compatibility, add support for querying
the maximum value of GL.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h   |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h   |  1 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c| 14 --
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h|  8 
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c   |  6 ++
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h  |  8 
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |  6 ++
 8 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 912c51e..f9d4d23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -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 */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index dc9a857..a5ebca8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 10990bd..be099dd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -420,7 +420,6 @@ enum hns3_flow_level_range {
HNS3_FLOW_ULTRA = 3,
 };
 
-#define HNS3_INT_GL_MAX0x1FE0
 #define HNS3_INT_GL_50K0x0014
 #define HNS3_INT_GL_20K0x0032
 #define HNS3_INT_GL_18K0x0036
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index ec8f4ca..49d3061 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1130,19 +1130,21 @@ 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;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 096e26a..5b7967c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -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)
 {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hn

[PATCH V4 net-next 4/4] net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce

2020-11-16 Thread Huazhong Tan
Besides GL(Gap Limiting), QL(Quantity Limiting) can be modified
dynamically when DIM is supported. So rename gl_adapt_enable as
adapt_enable in struct hns3_enet_coalesce.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 12 ++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  8 
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 2813fe5..999a2aa 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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.
 */
@@ -273,8 +273,8 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
 *
 * Default: enable interrupt coalescing self-adaptive and GL
 */
-   tx_coal->gl_adapt_enable = 1;
-   rx_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;
@@ -3384,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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 4651ad1..8d33652 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -436,7 +436,7 @@ struct hns3_enet_coalesce {
u16 int_gl;
u16 int_ql;
u16 int_ql_max;
-   u8 gl_adapt_enable:1;
+   u8 adapt_enable:1;
u8 ql_enable:1;
u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 09aa608..c30d5d3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1105,9 +1105,9 @@ 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;
@@ -1268,9 +1268,9 @@ 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;
-- 
2.7.4



[PATCH V4 net-next 3/4] net: hns3: add support for 1us unit GL configuration

2020-11-16 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL
configuration can set as 1us unit, so adds support for
configuring this field.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 26 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  3 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  6 +
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 6e08719..2813fe5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -224,17 +224,27 @@ 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(tx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET);
+   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,
@@ -272,6 +282,14 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
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;
+   }
+
if (ae_dev->dev_specs.int_ql_max) {
tx_coal->ql_enable = 1;
rx_coal->ql_enable = 1;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index be099dd..4651ad1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -425,6 +425,8 @@ enum hns3_flow_level_range {
 #define HNS3_INT_GL_18K0x0036
 #define HNS3_INT_GL_8K 0x007C
 
+#define HNS3_INT_GL_1USBIT(31)
+
 #define HNS3_INT_RL_MAX0x00EC
 #define HNS3_INT_RL_ENABLE_MASK0x40
 
@@ -436,6 +438,7 @@ struct hns3_enet_coalesce {
u16 int_ql_max;
u8 gl_adapt_enable:1;
u8 ql_enable:1;
+   u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 49d3061..09aa608 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1148,6 +1148,12 @@ static int hns3_check_gl_coalesce_para(struct net_device 
*netdev,
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,
-- 
2.7.4



[PATCH V4 net-next 0/4] net: hns3: updates for -next

2020-11-16 Thread Huazhong Tan
There are several updates relating to the interrupt coalesce for
the HNS3 ethernet driver.

#1 adds support for QL(quantity limiting, interrupt coalesce
   based on the frame quantity).
#2 queries the maximum value of GL from the firmware instead of
   a fixed value in code.
#3 adds support for 1us unit GL(gap limiting, interrupt coalesce
   based on the gap time).
#4 renames gl_adapt_enable in struct hns3_enet_coalesce to fit
   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-tanhuazh...@huawei.com/
V2: 
https://patchwork.ozlabs.org/project/netdev/cover/1604892159-19990-1-git-send-email-tanhuazh...@huawei.com/
V1: 
https://patchwork.ozlabs.org/project/netdev/cover/1604730681-32559-1-git-send-email-tanhuazh...@huawei.com/


Huazhong Tan (4):
  net: hns3: add support for configuring interrupt quantity limiting
  net: hns3: add support for querying maximum value of GL
  net: hns3: add support for 1us unit GL configuration
  net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 99 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 17 +++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 71 +---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  8 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  7 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  8 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  7 ++
 9 files changed, 182 insertions(+), 37 deletions(-)

-- 
2.7.4



[PATCH V4 net-next 1/4] net: hns3: add support for configuring interrupt quantity limiting

2020-11-16 Thread Huazhong Tan
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 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 65 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 13 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 43 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/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 a362516..6e08719 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = >tqp_vector[i];
-   hns3_vector_gl_rl_init_hw(tqp_vector, priv);
+   hns3_

[PATCH V3 net-next 10/10] net: hns3: add ethtool priv-flag for EQ/CQ

2020-11-11 Thread Huazhong Tan
Add a control private flag in ethtool for switching EQ/CQ mode.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  2 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 19 +++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 24 ++
 4 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 345e8a4..a452874 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -719,6 +719,8 @@ struct hnae3_roce_private_info {
 
 enum hnae3_pflag {
HNAE3_PFLAG_DIM_ENABLE,
+   HNAE3_PFLAG_TX_CQE_MODE,
+   HNAE3_PFLAG_RX_CQE_MODE,
HNAE3_PFLAG_MAX
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index d1243ea..93f7731 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4144,6 +4144,7 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
 
 static void hns3_state_init(struct hnae3_handle *handle)
 {
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev);
 
@@ -4151,10 +4152,24 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
+
+   /* device version above V3(include V3), GL can switch CQ/EQ period
+* mode.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+   set_bit(HNAE3_PFLAG_TX_CQE_MODE, >supported_pflags);
+   set_bit(HNAE3_PFLAG_RX_CQE_MODE, >supported_pflags);
+   }
+
+   if (priv->tx_cqe_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
+   handle->priv_flags |= BIT(HNAE3_PFLAG_TX_CQE_MODE);
+
+   if (priv->rx_cqe_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
+   handle->priv_flags |= BIT(HNAE3_PFLAG_RX_CQE_MODE);
 }
 
-static void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
-   enum dim_cq_period_mode mode, bool is_tx)
+void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode mode, bool is_tx)
 {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
struct hnae3_handle *handle = priv->ae_handle;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index c6c082a..ecdb544 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -635,4 +635,6 @@ void hns3_dbg_uninit(struct hnae3_handle *handle);
 void hns3_dbg_register_debugfs(const char *debugfs_dir_name);
 void hns3_dbg_unregister_debugfs(void);
 void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size);
+void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode mode, bool is_tx);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 7462d43..ba9c0fe 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -417,8 +417,32 @@ static void hns3_update_dim_state(struct net_device 
*netdev, bool enable)
hns3_update_state(netdev, HNS3_NIC_STATE_DIM_ENABLE, enable);
 }
 
+static void hns3_update_cqe_mode(struct net_device *netdev, bool enable,
+bool is_tx)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+   enum dim_cq_period_mode mode;
+
+   mode = enable ? DIM_CQ_PERIOD_MODE_START_FROM_CQE :
+   DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+
+   hns3_set_cq_period_mode(priv, mode, is_tx);
+}
+
+static void hns3_update_tx_cqe_mode(struct net_device *netdev, bool enable)
+{
+   hns3_update_cqe_mode(netdev, enable, true);
+}
+
+static void hns3_update_rx_cqe_mode(struct net_device *netdev, bool enable)
+{
+   hns3_update_cqe_mode(netdev, enable, false);
+}
+
 static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
{ "dim_enable", hns3_update_dim_state },
+   { "tx_cqe_mode",hns3_update_tx_cqe_mode },
+   { "rx_cqe_mode",hns3_update_rx_cqe_mode },
 };
 
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
-- 
2.7.4



[PATCH V3 net-next 06/10] net: hns3: add ethtool priv-flag for DIM

2020-11-11 Thread Huazhong Tan
Add a control private flag in ethtool for enable/disable
DIM feature.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  7 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 71 ++
 3 files changed, 79 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f9d4d23..18b3e43 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -716,6 +716,11 @@ struct hnae3_roce_private_info {
 #define HNAE3_UPE  (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
 #define HNAE3_MPE  (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
 
+enum hnae3_pflag {
+   HNAE3_PFLAG_DIM_ENABLE,
+   HNAE3_PFLAG_MAX
+};
+
 struct hnae3_handle {
struct hnae3_client *client;
struct pci_dev *pdev;
@@ -738,6 +743,8 @@ struct hnae3_handle {
 
/* Network interface message level enabled bits */
u32 msg_enable;
+
+   unsigned long priv_flags;
 };
 
 #define hnae3_set_field(origin, mask, shift, val) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 9e895b9..a567557 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4246,6 +4246,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
 
set_bit(HNS3_NIC_STATE_INITED, >state);
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
+   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
 
if (netif_msg_drv(handle))
hns3_info_show(priv);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index c30d5d3..e8adc70 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -18,6 +18,11 @@ struct hns3_sfp_type {
u8 ext_type;
 };
 
+struct hns3_pflag_desc {
+   char name[ETH_GSTRING_LEN];
+   void (*handler)(struct net_device *netdev, bool enable);
+};
+
 /* tqp related stats */
 #define HNS3_TQP_STAT(_string, _member){   \
.stats_string = _string,\
@@ -59,6 +64,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
 
+#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
+
 #define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
 
 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
@@ -394,6 +401,26 @@ static void hns3_self_test(struct net_device *ndev,
netif_dbg(h, drv, ndev, "self test end\n");
 }
 
+static void hns3_update_state(struct net_device *netdev,
+ enum hns3_nic_state state, bool enable)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+   if (enable)
+   set_bit(state, >state);
+   else
+   clear_bit(state, >state);
+}
+
+static void hns3_update_dim_state(struct net_device *netdev, bool enable)
+{
+   hns3_update_state(netdev, HNS3_NIC_STATE_DIM_ENABLE, enable);
+}
+
+static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
+   { "dim_enable", hns3_update_dim_state },
+};
+
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -410,6 +437,9 @@ static int hns3_get_sset_count(struct net_device *netdev, 
int stringset)
case ETH_SS_TEST:
return ops->get_sset_count(h, stringset);
 
+   case ETH_SS_PRIV_FLAGS:
+   return HNAE3_PFLAG_MAX;
+
default:
return -EOPNOTSUPP;
}
@@ -463,6 +493,7 @@ static void hns3_get_strings(struct net_device *netdev, u32 
stringset, u8 *data)
struct hnae3_handle *h = hns3_get_handle(netdev);
const struct hnae3_ae_ops *ops = h->ae_algo->ops;
char *buff = (char *)data;
+   int i;
 
if (!ops->get_strings)
return;
@@ -475,6 +506,13 @@ static void hns3_get_strings(struct net_device *netdev, 
u32 stringset, u8 *data)
case ETH_SS_TEST:
ops->get_strings(h, stringset, data);
break;
+   case ETH_SS_PRIV_FLAGS:
+   for (i = 0; i < HNS3_PRIV_FLAGS_LEN; i++) {
+   snprintf(buff, ETH_GSTRING_LEN, "%s",
+hns3_priv_flags[i].name);
+   buff += ETH_GSTRING_LEN;
+   }
+   break;
default:
break;
}
@@ -1516,6 +1554,35 @@ static int hns3_get_module_eeprom(struct net_device 
*netdev,
return ops->get_module_eeprom(handle, ee->offset, ee->len, data);

[PATCH V3 net-next 09/10] net: hns3: add support for EQ/CQ mode configuration

2020-11-11 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL can
select EQ or CQ mode, so adds support for it.

In CQ mode, the coalesced timer will restart when the first new
completion occurs, while in EQ mode, the timer will not restart.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 49 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  8 
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  1 +
 5 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 3642740..345e8a4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -684,6 +684,7 @@ struct hnae3_knic_private_info {
 
u16 int_rl_setting;
enum pkt_hash_types rss_type;
+   void __iomem *io_base;
 };
 
 struct hnae3_roce_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index c30cf9e..d1243ea 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3653,9 +3653,7 @@ static void hns3_tx_dim_work(struct work_struct *work)
 static void hns3_nic_init_dim(struct hns3_enet_tqp_vector *tqp_vector)
 {
INIT_WORK(_vector->rx_group.dim.work, hns3_rx_dim_work);
-   tqp_vector->rx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(_vector->tx_group.dim.work, hns3_tx_dim_work);
-   tqp_vector->tx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 }
 
 static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
@@ -4155,6 +4153,48 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
 }
 
+static void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+   enum dim_cq_period_mode mode, bool is_tx)
+{
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
+   struct hnae3_handle *handle = priv->ae_handle;
+   int i;
+
+   if (is_tx) {
+   priv->tx_cqe_mode = mode;
+
+   for (i = 0; i < priv->vector_num; i++)
+   priv->tqp_vector[i].tx_group.dim.mode = mode;
+   } else {
+   priv->rx_cqe_mode = mode;
+
+   for (i = 0; i < priv->vector_num; i++)
+   priv->tqp_vector[i].rx_group.dim.mode = mode;
+   }
+
+   /* only device version above V3(include V3), GL can switch CQ/EQ
+* period mode.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+   u32 new_mode;
+   u64 reg;
+
+   new_mode = (mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE) ?
+   HNS3_CQ_MODE_CQE : HNS3_CQ_MODE_EQE;
+   reg = is_tx ? HNS3_GL1_CQ_MODE_REG : HNS3_GL0_CQ_MODE_REG;
+
+   writel(new_mode, handle->kinfo.io_base + reg);
+   }
+}
+
+static void hns3_cq_period_mode_init(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode tx_mode,
+enum dim_cq_period_mode rx_mode)
+{
+   hns3_set_cq_period_mode(priv, tx_mode, true);
+   hns3_set_cq_period_mode(priv, rx_mode, false);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
struct pci_dev *pdev = handle->pdev;
@@ -4220,6 +4260,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_init_ring;
}
 
+   hns3_cq_period_mode_init(priv, DIM_CQ_PERIOD_MODE_START_FROM_EQE,
+DIM_CQ_PERIOD_MODE_START_FROM_EQE);
+
ret = hns3_init_phy(netdev);
if (ret)
goto out_init_phy;
@@ -4580,6 +4623,8 @@ static int hns3_reset_notify_init_enet(struct 
hnae3_handle *handle)
if (ret)
goto err_uninit_vector;
 
+   hns3_cq_period_mode_init(priv, priv->tx_cqe_mode, priv->rx_cqe_mode);
+
/* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(netdev);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index eb4e7ef..c6c082a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -188,6 +188,12 @@ enum hns3_nic_state {
 
 #define HNS3_RING_EN_B 0
 
+#define HNS3_GL0_CQ_MODE_REG   0x20d00
+#define HNS3_GL1_CQ_MODE_REG   0x20d04
+#define HNS3_GL2_CQ_MODE_REG   0x20d08
+#define HNS3_CQ_MODE_EQE   1U
+#define HNS3_CQ_MODE_CQE

[PATCH V3 net-next 01/10] net: hns3: add support for configuring interrupt quantity limiting

2020-11-11 Thread Huazhong Tan
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 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 65 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 13 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 43 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/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 a362516..6e08719 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = >tqp_vector[i];
-   hns3_vector_gl_rl_init_hw(tqp_vector, priv);
+   hns3_

[PATCH V3 net-next 04/10] net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce

2020-11-11 Thread Huazhong Tan
Besides GL(Gap Limiting), QL(Quantity Limiting) can be modified
dynamically when DIM is supported. So rename gl_adapt_enable as
adapt_enable in struct hns3_enet_coalesce.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 12 ++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  8 
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 2813fe5..999a2aa 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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.
 */
@@ -273,8 +273,8 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
 *
 * Default: enable interrupt coalescing self-adaptive and GL
 */
-   tx_coal->gl_adapt_enable = 1;
-   rx_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;
@@ -3384,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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 4651ad1..8d33652 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -436,7 +436,7 @@ struct hns3_enet_coalesce {
u16 int_gl;
u16 int_ql;
u16 int_ql_max;
-   u8 gl_adapt_enable:1;
+   u8 adapt_enable:1;
u8 ql_enable:1;
u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 09aa608..c30d5d3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1105,9 +1105,9 @@ 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;
@@ -1268,9 +1268,9 @@ 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;
-- 
2.7.4



[PATCH V3 net-next 07/10] net: hns3: add hns3_state_init() to do state initialization

2020-11-11 Thread Huazhong Tan
To improve the readability and maintainability, add hns3_state_init()
to initialize the state.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a567557..f686723 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4144,6 +4144,16 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
dev_info(priv->dev, "Max mtu size: %u\n", priv->netdev->max_mtu);
 }
 
+static void hns3_state_init(struct hnae3_handle *handle)
+{
+   struct net_device *netdev = handle->kinfo.netdev;
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+   set_bit(HNS3_NIC_STATE_INITED, >state);
+   set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
+   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
struct pci_dev *pdev = handle->pdev;
@@ -4244,9 +4254,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
/* MTU range: (ETH_MIN_MTU(kernel default) - 9702) */
netdev->max_mtu = HNS3_MAX_MTU;
 
-   set_bit(HNS3_NIC_STATE_INITED, >state);
-   set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
-   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+   hns3_state_init(handle);
 
if (netif_msg_drv(handle))
hns3_info_show(priv);
-- 
2.7.4



[PATCH V3 net-next 08/10] net: hns3: add a check for ethtool priv-flag interface

2020-11-11 Thread Huazhong Tan
Add a check for hns3_set_priv_flags() since if the capability
is unsupported its private flags should not be modified as well.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 19 +++
 3 files changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 18b3e43..3642740 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -744,6 +744,7 @@ struct hnae3_handle {
/* Network interface message level enabled bits */
u32 msg_enable;
 
+   unsigned long supported_pflags;
unsigned long priv_flags;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index f686723..c30cf9e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4152,6 +4152,7 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_INITED, >state);
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+   set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
 }
 
 static int hns3_client_init(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 e8adc70..7462d43 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1561,12 +1561,31 @@ static u32 hns3_get_priv_flags(struct net_device 
*netdev)
return handle->priv_flags;
 }
 
+static int hns3_check_priv_flags(struct hnae3_handle *h, u32 changed)
+{
+   u32 i;
+
+   for (i = 0; i < HNAE3_PFLAG_MAX; i++)
+   if ((changed & BIT(i)) && !test_bit(i, >supported_pflags)) {
+   netdev_err(h->netdev, "%s is unsupported\n",
+  hns3_priv_flags[i].name);
+   return -EOPNOTSUPP;
+   }
+
+   return 0;
+}
+
 static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
 {
struct hnae3_handle *handle = hns3_get_handle(netdev);
u32 changed = pflags ^ handle->priv_flags;
+   int ret;
u32 i;
 
+   ret = hns3_check_priv_flags(handle, changed);
+   if (ret)
+   return ret;
+
for (i = 0; i < HNAE3_PFLAG_MAX; i++) {
if (changed & BIT(i)) {
bool enable = !(handle->priv_flags & BIT(i));
-- 
2.7.4



[PATCH V3 net-next 05/10] net: hns3: add support for dynamic interrupt moderation

2020-11-11 Thread Huazhong Tan
Add dynamic interrupt moderation support for the HNS3 driver.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/Kconfig  |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 87 -
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h |  4 ++
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 44f9279..fa6025d 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -130,6 +130,7 @@ config HNS3_ENET
default m
depends on 64BIT && PCI
depends on INET
+   select DIMLIB
help
  This selects the Ethernet Driver for Hisilicon Network Subsystem 3 
for hip08
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 999a2aa..9e895b9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -96,6 +96,7 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
struct hns3_enet_tqp_vector *tqp_vector = vector;
 
napi_schedule_irqoff(_vector->napi);
+   tqp_vector->event_cnt++;
 
return IRQ_HANDLED;
 }
@@ -199,6 +200,8 @@ static void hns3_vector_disable(struct hns3_enet_tqp_vector 
*tqp_vector)
 
disable_irq(tqp_vector->vector_irq);
napi_disable(_vector->napi);
+   cancel_work_sync(_vector->rx_group.dim.work);
+   cancel_work_sync(_vector->tx_group.dim.work);
 }
 
 void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
@@ -3401,6 +3404,32 @@ static void hns3_update_new_int_gl(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->last_jiffies = jiffies;
 }
 
+static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *rx_group = _vector->rx_group;
+   struct dim_sample sample = {};
+
+   if (!rx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, rx_group->total_packets,
+ rx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
+static void hns3_update_tx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *tx_group = _vector->tx_group;
+   struct dim_sample sample = {};
+
+   if (!tx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, tx_group->total_packets,
+ tx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
 static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
 {
struct hns3_nic_priv *priv = netdev_priv(napi->dev);
@@ -3444,7 +3473,13 @@ static int hns3_nic_common_poll(struct napi_struct 
*napi, int budget)
 
if (napi_complete(napi) &&
likely(!test_bit(HNS3_NIC_STATE_DOWN, >state))) {
-   hns3_update_new_int_gl(tqp_vector);
+   if (test_bit(HNS3_NIC_STATE_DIM_ENABLE, >state)) {
+   hns3_update_rx_int_coalesce(tqp_vector);
+   hns3_update_tx_int_coalesce(tqp_vector);
+   } else {
+   hns3_update_new_int_gl(tqp_vector);
+   }
+
hns3_mask_vector_irq(tqp_vector, 1);
}
 
@@ -3575,6 +3610,54 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv 
*priv)
}
 }
 
+static void hns3_rx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+
+   hns3_set_vector_coalesce_rx_gl(group->ring->tqp_vector, cur_moder.usec);
+   tqp_vector->rx_group.coal.int_gl = cur_moder.usec;
+
+   if (cur_moder.pkts < tqp_vector->rx_group.coal.int_ql_max) {
+   hns3_set_vector_coalesce_rx_ql(tqp_vector, cur_moder.pkts);
+   tqp_vector->rx_group.coal.int_ql = cur_moder.pkts;
+   }
+
+   dim->state = DIM_START_MEASURE;
+}
+
+static void hns3_tx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_tx_moderation(dim->mode, dim->profile_ix);

[PATCH V3 net-next 00/10] net: hns3: updates for -next

2020-11-11 Thread Huazhong Tan
There are several updates relating to the interrupt coalesce for
the HNS3 ethernet driver.

#1 adds support for QL(quantity limiting, interrupt coalesce
   based on the frame quantity).
#2 queries the maximum value of GL from the firmware instead of
   a fixed value in code.
#3 adds support for 1us unit GL(gap limiting, interrupt coalesce
   based on the gap time).
#4 renames gl_adapt_enable in struct hns3_enet_coalesce to fit
   its new usage.
#5 & #6 adds support for the dynamic interrupt moderation,
   and adds a control private flag in ethtool.
#7 adds wrapper function for state initialization.
#8 adds a check for the read-only private flag.
#9 & #10 adds support for EQ/CQ configuration, and adds a control
   private flag in ethtool.

change log:
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:
V2: 
https://patchwork.ozlabs.org/project/netdev/cover/1604892159-19990-1-git-send-email-tanhuazh...@huawei.com/
V1: 
https://patchwork.ozlabs.org/project/netdev/cover/1604730681-32559-1-git-send-email-tanhuazh...@huawei.com/

Huazhong Tan (10):
  net: hns3: add support for configuring interrupt quantity limiting
  net: hns3: add support for querying maximum value of GL
  net: hns3: add support for 1us unit GL configuration
  net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce
  net: hns3: add support for dynamic interrupt moderation
  net: hns3: add ethtool priv-flag for DIM
  net: hns3: add hns3_state_init() to do state initialization
  net: hns3: add a check for ethtool priv-flag interface
  net: hns3: add support for EQ/CQ mode configuration
  net: hns3: add ethtool priv-flag for EQ/CQ

 drivers/net/ethernet/hisilicon/Kconfig |   1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  12 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |   1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 258 ++---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  31 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 185 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   8 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|   8 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |   8 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |   8 +
 10 files changed, 481 insertions(+), 39 deletions(-)

-- 
2.7.4



[PATCH V3 net-next 03/10] net: hns3: add support for 1us unit GL configuration

2020-11-11 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL
configuration can set as 1us unit, so adds support for
configuring this field.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 26 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  3 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  6 +
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 6e08719..2813fe5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -224,17 +224,27 @@ 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(tx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET);
+   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,
@@ -272,6 +282,14 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
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;
+   }
+
if (ae_dev->dev_specs.int_ql_max) {
tx_coal->ql_enable = 1;
rx_coal->ql_enable = 1;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index be099dd..4651ad1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -425,6 +425,8 @@ enum hns3_flow_level_range {
 #define HNS3_INT_GL_18K0x0036
 #define HNS3_INT_GL_8K 0x007C
 
+#define HNS3_INT_GL_1USBIT(31)
+
 #define HNS3_INT_RL_MAX0x00EC
 #define HNS3_INT_RL_ENABLE_MASK0x40
 
@@ -436,6 +438,7 @@ struct hns3_enet_coalesce {
u16 int_ql_max;
u8 gl_adapt_enable:1;
u8 ql_enable:1;
+   u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 49d3061..09aa608 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1148,6 +1148,12 @@ static int hns3_check_gl_coalesce_para(struct net_device 
*netdev,
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,
-- 
2.7.4



[PATCH V3 net-next 02/10] net: hns3: add support for querying maximum value of GL

2020-11-11 Thread Huazhong Tan
For maintainability and compatibility, add support for querying
the maximum value of GL.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h   |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h   |  1 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c| 14 --
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h|  8 
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c   |  6 ++
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h  |  8 
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |  6 ++
 8 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 912c51e..f9d4d23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -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 */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index dc9a857..a5ebca8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 10990bd..be099dd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -420,7 +420,6 @@ enum hns3_flow_level_range {
HNS3_FLOW_ULTRA = 3,
 };
 
-#define HNS3_INT_GL_MAX0x1FE0
 #define HNS3_INT_GL_50K0x0014
 #define HNS3_INT_GL_20K0x0032
 #define HNS3_INT_GL_18K0x0036
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index ec8f4ca..49d3061 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1130,19 +1130,21 @@ 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;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 096e26a..5b7967c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -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)
 {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hn

[PATCH V2 net-next 03/11] net: hns3: add support for 1us unit GL configuration

2020-11-08 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL
configuration can set as 1us unit, so adds support for
configuring this field.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 26 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  3 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  6 +
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 6e08719..2813fe5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -224,17 +224,27 @@ 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(tx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET);
+   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,
@@ -272,6 +282,14 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
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;
+   }
+
if (ae_dev->dev_specs.int_ql_max) {
tx_coal->ql_enable = 1;
rx_coal->ql_enable = 1;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index be099dd..4651ad1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -425,6 +425,8 @@ enum hns3_flow_level_range {
 #define HNS3_INT_GL_18K0x0036
 #define HNS3_INT_GL_8K 0x007C
 
+#define HNS3_INT_GL_1USBIT(31)
+
 #define HNS3_INT_RL_MAX0x00EC
 #define HNS3_INT_RL_ENABLE_MASK0x40
 
@@ -436,6 +438,7 @@ struct hns3_enet_coalesce {
u16 int_ql_max;
u8 gl_adapt_enable:1;
u8 ql_enable:1;
+   u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 9e90d67..8d5c194 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1148,6 +1148,12 @@ static int hns3_check_gl_coalesce_para(struct net_device 
*netdev,
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,
-- 
2.7.4



[PATCH V2 net-next 00/11] net: hns3: updates for -next

2020-11-08 Thread Huazhong Tan
There are several updates relating to the interrupt coalesce for
the HNS3 ethernet driver.

#1 adds support for QL(quantity limiting, interrupt coalesce
   based on the frame quantity).
#2 queries the maximum value of GL from the firmware instead of
   a fixed value in code.
#3 adds support for 1us unit GL(gap limiting, interrupt coalesce
   based on the gap time).
#4 renames gl_adapt_enable in struct hns3_enet_coalesce to fit
   its new usage.
#5 & #6 adds support for the dynamic interrupt moderation,
   and adds a control private flag in ethtool.
#7 adds wrapper function for state initialization.
#8 adds a check for the read-only private flag.
#9 & #10 adds support for EQ/CQ configuration, and adds a control
   private flag in ethtool.
#11 adds debugfs support for interrupt coalesce.

change log:
V2 - reorder #2 & #3 to fix compiler error.
 fix some checkpatch warnings in #10 & #11.

previous version:
V1: 
https://patchwork.ozlabs.org/project/netdev/cover/1604730681-32559-1-git-send-email-tanhuazh...@huawei.com/

Huazhong Tan (11):
  net: hns3: add support for configuring interrupt quantity limiting
  net: hns3: add support for querying maximum value of GL
  net: hns3: add support for 1us unit GL configuration
  net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce
  net: hns3: add support for dynamic interrupt moderation
  net: hns3: add ethtool priv-flag for DIM
  net: hns3: add hns3_state_init() to do state initialization
  net: hns3: add a check for ethtool priv-flag interface
  net: hns3: add support for EQ/CQ mode configuration
  net: hns3: add ethtool priv-flag for EQ/CQ
  net: hns3: add debugfs support for interrupt coalesce

 drivers/net/ethernet/hisilicon/Kconfig |   1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  12 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 127 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 258 ++---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  31 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 185 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   8 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|   8 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |   8 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |   8 +
 10 files changed, 607 insertions(+), 39 deletions(-)

-- 
2.7.4



[PATCH V2 net-next 08/11] net: hns3: add a check for ethtool priv-flag interface

2020-11-08 Thread Huazhong Tan
Add a check for hns3_set_priv_flags() since if the capability
is unsupported its private flags should not be modified as well.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 19 +++
 3 files changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 18b3e43..3642740 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -744,6 +744,7 @@ struct hnae3_handle {
/* Network interface message level enabled bits */
u32 msg_enable;
 
+   unsigned long supported_pflags;
unsigned long priv_flags;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index f686723..c30cf9e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4152,6 +4152,7 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_INITED, >state);
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+   set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
 }
 
 static int hns3_client_init(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 427b72c..6904c0a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1561,12 +1561,31 @@ static u32 hns3_get_priv_flags(struct net_device 
*netdev)
return handle->priv_flags;
 }
 
+static int hns3_check_priv_flags(struct hnae3_handle *h, u32 changed)
+{
+   u32 i;
+
+   for (i = 0; i < HNAE3_PFLAG_MAX; i++)
+   if ((changed & BIT(i)) && !test_bit(i, >supported_pflags)) {
+   netdev_err(h->netdev, "%s is unsupported\n",
+  hns3_priv_flags[i].name);
+   return -EOPNOTSUPP;
+   }
+
+   return 0;
+}
+
 static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
 {
struct hnae3_handle *handle = hns3_get_handle(netdev);
u32 changed = pflags ^ handle->priv_flags;
+   int ret;
u32 i;
 
+   ret = hns3_check_priv_flags(handle, changed);
+   if (ret)
+   return ret;
+
for (i = 0; i < HNAE3_PFLAG_MAX; i++) {
if (changed & BIT(i)) {
bool enable = !(handle->priv_flags & BIT(i));
-- 
2.7.4



[PATCH V2 net-next 09/11] net: hns3: add support for EQ/CQ mode configuration

2020-11-08 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL can
select EQ or CQ mode, so adds support for it.

In CQ mode, the coalesced timer will restart upon new completion,
while in EQ mode, the timer will not restart.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 49 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  8 
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  1 +
 5 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 3642740..345e8a4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -684,6 +684,7 @@ struct hnae3_knic_private_info {
 
u16 int_rl_setting;
enum pkt_hash_types rss_type;
+   void __iomem *io_base;
 };
 
 struct hnae3_roce_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index c30cf9e..d1243ea 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3653,9 +3653,7 @@ static void hns3_tx_dim_work(struct work_struct *work)
 static void hns3_nic_init_dim(struct hns3_enet_tqp_vector *tqp_vector)
 {
INIT_WORK(_vector->rx_group.dim.work, hns3_rx_dim_work);
-   tqp_vector->rx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(_vector->tx_group.dim.work, hns3_tx_dim_work);
-   tqp_vector->tx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 }
 
 static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
@@ -4155,6 +4153,48 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
 }
 
+static void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+   enum dim_cq_period_mode mode, bool is_tx)
+{
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
+   struct hnae3_handle *handle = priv->ae_handle;
+   int i;
+
+   if (is_tx) {
+   priv->tx_cqe_mode = mode;
+
+   for (i = 0; i < priv->vector_num; i++)
+   priv->tqp_vector[i].tx_group.dim.mode = mode;
+   } else {
+   priv->rx_cqe_mode = mode;
+
+   for (i = 0; i < priv->vector_num; i++)
+   priv->tqp_vector[i].rx_group.dim.mode = mode;
+   }
+
+   /* only device version above V3(include V3), GL can switch CQ/EQ
+* period mode.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+   u32 new_mode;
+   u64 reg;
+
+   new_mode = (mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE) ?
+   HNS3_CQ_MODE_CQE : HNS3_CQ_MODE_EQE;
+   reg = is_tx ? HNS3_GL1_CQ_MODE_REG : HNS3_GL0_CQ_MODE_REG;
+
+   writel(new_mode, handle->kinfo.io_base + reg);
+   }
+}
+
+static void hns3_cq_period_mode_init(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode tx_mode,
+enum dim_cq_period_mode rx_mode)
+{
+   hns3_set_cq_period_mode(priv, tx_mode, true);
+   hns3_set_cq_period_mode(priv, rx_mode, false);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
struct pci_dev *pdev = handle->pdev;
@@ -4220,6 +4260,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_init_ring;
}
 
+   hns3_cq_period_mode_init(priv, DIM_CQ_PERIOD_MODE_START_FROM_EQE,
+DIM_CQ_PERIOD_MODE_START_FROM_EQE);
+
ret = hns3_init_phy(netdev);
if (ret)
goto out_init_phy;
@@ -4580,6 +4623,8 @@ static int hns3_reset_notify_init_enet(struct 
hnae3_handle *handle)
if (ret)
goto err_uninit_vector;
 
+   hns3_cq_period_mode_init(priv, priv->tx_cqe_mode, priv->rx_cqe_mode);
+
/* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(netdev);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index eb4e7ef..c6c082a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -188,6 +188,12 @@ enum hns3_nic_state {
 
 #define HNS3_RING_EN_B 0
 
+#define HNS3_GL0_CQ_MODE_REG   0x20d00
+#define HNS3_GL1_CQ_MODE_REG   0x20d04
+#define HNS3_GL2_CQ_MODE_REG   0x20d08
+#define HNS3_CQ_MODE_EQE   1U
+#define HNS3_CQ_MODE_CQE

[PATCH V2 net-next 05/11] net: hns3: add support for dynamic interrupt moderation

2020-11-08 Thread Huazhong Tan
Add dynamic interrupt moderation support for the HNS3 driver.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/Kconfig  |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 87 -
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h |  4 ++
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 44f9279..fa6025d 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -130,6 +130,7 @@ config HNS3_ENET
default m
depends on 64BIT && PCI
depends on INET
+   select DIMLIB
help
  This selects the Ethernet Driver for Hisilicon Network Subsystem 3 
for hip08
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 999a2aa..9e895b9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -96,6 +96,7 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
struct hns3_enet_tqp_vector *tqp_vector = vector;
 
napi_schedule_irqoff(_vector->napi);
+   tqp_vector->event_cnt++;
 
return IRQ_HANDLED;
 }
@@ -199,6 +200,8 @@ static void hns3_vector_disable(struct hns3_enet_tqp_vector 
*tqp_vector)
 
disable_irq(tqp_vector->vector_irq);
napi_disable(_vector->napi);
+   cancel_work_sync(_vector->rx_group.dim.work);
+   cancel_work_sync(_vector->tx_group.dim.work);
 }
 
 void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
@@ -3401,6 +3404,32 @@ static void hns3_update_new_int_gl(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->last_jiffies = jiffies;
 }
 
+static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *rx_group = _vector->rx_group;
+   struct dim_sample sample = {};
+
+   if (!rx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, rx_group->total_packets,
+ rx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
+static void hns3_update_tx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *tx_group = _vector->tx_group;
+   struct dim_sample sample = {};
+
+   if (!tx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, tx_group->total_packets,
+ tx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
 static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
 {
struct hns3_nic_priv *priv = netdev_priv(napi->dev);
@@ -3444,7 +3473,13 @@ static int hns3_nic_common_poll(struct napi_struct 
*napi, int budget)
 
if (napi_complete(napi) &&
likely(!test_bit(HNS3_NIC_STATE_DOWN, >state))) {
-   hns3_update_new_int_gl(tqp_vector);
+   if (test_bit(HNS3_NIC_STATE_DIM_ENABLE, >state)) {
+   hns3_update_rx_int_coalesce(tqp_vector);
+   hns3_update_tx_int_coalesce(tqp_vector);
+   } else {
+   hns3_update_new_int_gl(tqp_vector);
+   }
+
hns3_mask_vector_irq(tqp_vector, 1);
}
 
@@ -3575,6 +3610,54 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv 
*priv)
}
 }
 
+static void hns3_rx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+
+   hns3_set_vector_coalesce_rx_gl(group->ring->tqp_vector, cur_moder.usec);
+   tqp_vector->rx_group.coal.int_gl = cur_moder.usec;
+
+   if (cur_moder.pkts < tqp_vector->rx_group.coal.int_ql_max) {
+   hns3_set_vector_coalesce_rx_ql(tqp_vector, cur_moder.pkts);
+   tqp_vector->rx_group.coal.int_ql = cur_moder.pkts;
+   }
+
+   dim->state = DIM_START_MEASURE;
+}
+
+static void hns3_tx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_tx_moderation(dim->mode, dim->profile_ix);

[PATCH V2 net-next 07/11] net: hns3: add hns3_state_init() to do state initialization

2020-11-08 Thread Huazhong Tan
To improve the readability and maintainability, add hns3_state_init()
to initialize the state.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a567557..f686723 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4144,6 +4144,16 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
dev_info(priv->dev, "Max mtu size: %u\n", priv->netdev->max_mtu);
 }
 
+static void hns3_state_init(struct hnae3_handle *handle)
+{
+   struct net_device *netdev = handle->kinfo.netdev;
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+   set_bit(HNS3_NIC_STATE_INITED, >state);
+   set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
+   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
struct pci_dev *pdev = handle->pdev;
@@ -4244,9 +4254,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
/* MTU range: (ETH_MIN_MTU(kernel default) - 9702) */
netdev->max_mtu = HNS3_MAX_MTU;
 
-   set_bit(HNS3_NIC_STATE_INITED, >state);
-   set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
-   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+   hns3_state_init(handle);
 
if (netif_msg_drv(handle))
hns3_info_show(priv);
-- 
2.7.4



[PATCH V2 net-next 11/11] net: hns3: add debugfs support for interrupt coalesce

2020-11-08 Thread Huazhong Tan
Since user may need to check the current configuration of the
interrupt coalesce, so add debugfs support for query this info,
which includes DIM profile, coalesce configuration of both software
and hardware.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 126 +
 1 file changed, 126 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index a5ebca8..26fa69a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -12,6 +12,93 @@
 
 static struct dentry *hns3_dbgfs_root;
 
+static ssize_t hns3_dbg_coal_write(struct file *filp, const char __user 
*buffer,
+  size_t count, loff_t *ppos)
+{
+   struct hnae3_handle *h = filp->private_data;
+   struct hns3_nic_priv *priv  = h->priv;
+   struct hns3_enet_tqp_vector *tqp_vector;
+   struct hns3_enet_coalesce *coal;
+   u8 __iomem *base_addr;
+   int uncopied_bytes;
+   unsigned int idx;
+   struct dim *dim;
+   char *cmd_buf;
+
+   if (*ppos != 0)
+   return 0;
+
+   if (!test_bit(HNS3_NIC_STATE_INITED, >state)) {
+   dev_err(>pdev->dev, "device is not initialized\n");
+   return -EFAULT;
+   }
+
+   cmd_buf = kzalloc(count + 1, GFP_KERNEL);
+   if (!cmd_buf)
+   return -ENOMEM;
+
+   uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
+   if (uncopied_bytes) {
+   kfree(cmd_buf);
+   return -EFAULT;
+   }
+
+   cmd_buf[count] = '\0';
+
+   if (kstrtouint(cmd_buf, 0, ))
+   idx = 0;
+
+   if (idx >= priv->vector_num) {
+   dev_err(>pdev->dev,
+   "vector index(%u) is out of range(0-%u)\n", idx,
+   priv->vector_num - 1);
+   kfree(cmd_buf);
+   return -EINVAL;
+   }
+
+   tqp_vector = >tqp_vector[idx];
+   coal = _vector->tx_group.coal;
+   dim = _vector->tx_group.dim;
+   base_addr = tqp_vector->mask_addr;
+
+   dev_info(>pdev->dev, "vector[%u] interrupt coalesce info:\n", idx);
+   dev_info(>pdev->dev,
+"TX DIM info state = %d profile_ix = %d mode = %d tune_state = 
%d steps_right = %d steps_left = %d tired = %d\n",
+dim->state, dim->profile_ix, dim->mode, dim->tune_state,
+dim->steps_right, dim->steps_left, dim->tired);
+
+   dev_info(>pdev->dev, "TX GL info sw_gl = %u, hw_gl = %u\n",
+coal->int_gl,
+readl(base_addr + HNS3_VECTOR_GL1_OFFSET));
+
+   if (coal->ql_enable)
+   dev_info(>pdev->dev, "TX QL info sw_ql = %u, hw_ql = %u\n",
+coal->int_ql,
+readl(base_addr + HNS3_VECTOR_TX_QL_OFFSET));
+
+   coal = _vector->rx_group.coal;
+   dim = _vector->rx_group.dim;
+
+   dev_info(>pdev->dev,
+"RX dim_info state = %d profile_ix = %d mode = %d tune_state = 
%d steps_right = %d steps_left = %d tired = %d\n",
+dim->state, dim->profile_ix, dim->mode, dim->tune_state,
+dim->steps_right, dim->steps_left, dim->tired);
+
+   dev_info(>pdev->dev, "RX GL info sw_gl = %u, hw_gl = %u\n",
+coal->int_gl,
+readl(base_addr + HNS3_VECTOR_GL0_OFFSET));
+
+   if (coal->ql_enable)
+   dev_info(>pdev->dev, "RX QL info sw_ql = %u, hw_ql = %u\n",
+coal->int_ql,
+readl(base_addr + HNS3_VECTOR_RX_QL_OFFSET));
+
+   kfree(cmd_buf);
+   cmd_buf = NULL;
+
+   return count;
+}
+
 static int hns3_dbg_queue_info(struct hnae3_handle *h,
   const char *cmd_buf)
 {
@@ -352,6 +439,35 @@ static void hns3_dbg_dev_specs(struct hnae3_handle *h)
dev_info(priv->dev, "MAX INT GL: %u\n", dev_specs->max_int_gl);
 }
 
+static ssize_t hns3_dbg_coal_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+   int uncopy_bytes;
+   char *buf;
+   int len;
+
+   if (*ppos != 0)
+   return 0;
+
+   if (count < HNS3_DBG_READ_LEN)
+   return -ENOSPC;
+
+   buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
+   "Please echo index to coal");
+   uncopy_bytes = copy_to_user(buffer, buf, len);
+
+   kfree(buf);
+
+   if (uncopy_bytes)
+   retur

[PATCH V2 net-next 02/11] net: hns3: add support for querying maximum value of GL

2020-11-08 Thread Huazhong Tan
For maintainability and compatibility, add support for querying
the maximum value of GL.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h   |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h   |  1 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c| 14 --
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h|  8 
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c   |  6 ++
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h  |  8 
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |  6 ++
 8 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 912c51e..f9d4d23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -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 */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index dc9a857..a5ebca8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 10990bd..be099dd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -420,7 +420,6 @@ enum hns3_flow_level_range {
HNS3_FLOW_ULTRA = 3,
 };
 
-#define HNS3_INT_GL_MAX0x1FE0
 #define HNS3_INT_GL_50K0x0014
 #define HNS3_INT_GL_20K0x0032
 #define HNS3_INT_GL_18K0x0036
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 9af7cb9..9e90d67 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1130,19 +1130,21 @@ 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;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 096e26a..5b7967c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -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)
 {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hn

[PATCH V2 net-next 10/11] net: hns3: add ethtool priv-flag for EQ/CQ

2020-11-08 Thread Huazhong Tan
Add a control private flag in ethtool for switching EQ/CQ mode.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  2 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 19 +++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 24 ++
 4 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 345e8a4..a452874 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -719,6 +719,8 @@ struct hnae3_roce_private_info {
 
 enum hnae3_pflag {
HNAE3_PFLAG_DIM_ENABLE,
+   HNAE3_PFLAG_TX_CQE_MODE,
+   HNAE3_PFLAG_RX_CQE_MODE,
HNAE3_PFLAG_MAX
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index d1243ea..93f7731 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4144,6 +4144,7 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
 
 static void hns3_state_init(struct hnae3_handle *handle)
 {
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev);
 
@@ -4151,10 +4152,24 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
+
+   /* device version above V3(include V3), GL can switch CQ/EQ period
+* mode.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+   set_bit(HNAE3_PFLAG_TX_CQE_MODE, >supported_pflags);
+   set_bit(HNAE3_PFLAG_RX_CQE_MODE, >supported_pflags);
+   }
+
+   if (priv->tx_cqe_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
+   handle->priv_flags |= BIT(HNAE3_PFLAG_TX_CQE_MODE);
+
+   if (priv->rx_cqe_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
+   handle->priv_flags |= BIT(HNAE3_PFLAG_RX_CQE_MODE);
 }
 
-static void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
-   enum dim_cq_period_mode mode, bool is_tx)
+void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode mode, bool is_tx)
 {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
struct hnae3_handle *handle = priv->ae_handle;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index c6c082a..ecdb544 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -635,4 +635,6 @@ void hns3_dbg_uninit(struct hnae3_handle *handle);
 void hns3_dbg_register_debugfs(const char *debugfs_dir_name);
 void hns3_dbg_unregister_debugfs(void);
 void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size);
+void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode mode, bool is_tx);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 6904c0a..cfc0766 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -417,8 +417,32 @@ static void hns3_update_dim_state(struct net_device 
*netdev, bool enable)
hns3_update_state(netdev, HNS3_NIC_STATE_DIM_ENABLE, enable);
 }
 
+static void hns3_update_cqe_mode(struct net_device *netdev, bool enable,
+bool is_tx)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+   enum dim_cq_period_mode mode;
+
+   mode = enable ? DIM_CQ_PERIOD_MODE_START_FROM_CQE :
+   DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+
+   hns3_set_cq_period_mode(priv, mode, is_tx);
+}
+
+static void hns3_update_tx_cqe_mode(struct net_device *netdev, bool enable)
+{
+   hns3_update_cqe_mode(netdev, enable, true);
+}
+
+static void hns3_update_rx_cqe_mode(struct net_device *netdev, bool enable)
+{
+   hns3_update_cqe_mode(netdev, enable, false);
+}
+
 static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
{ "dim_enable", hns3_update_dim_state },
+   { "tx_cqe_mode",hns3_update_tx_cqe_mode },
+   { "rx_cqe_mode",hns3_update_rx_cqe_mode },
 };
 
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
-- 
2.7.4



[PATCH V2 net-next 06/11] net: hns3: add ethtool priv-flag for DIM

2020-11-08 Thread Huazhong Tan
Add a control private flag in ethtool for enable/disable
DIM feature.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  7 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 71 ++
 3 files changed, 79 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f9d4d23..18b3e43 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -716,6 +716,11 @@ struct hnae3_roce_private_info {
 #define HNAE3_UPE  (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
 #define HNAE3_MPE  (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
 
+enum hnae3_pflag {
+   HNAE3_PFLAG_DIM_ENABLE,
+   HNAE3_PFLAG_MAX
+};
+
 struct hnae3_handle {
struct hnae3_client *client;
struct pci_dev *pdev;
@@ -738,6 +743,8 @@ struct hnae3_handle {
 
/* Network interface message level enabled bits */
u32 msg_enable;
+
+   unsigned long priv_flags;
 };
 
 #define hnae3_set_field(origin, mask, shift, val) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 9e895b9..a567557 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4246,6 +4246,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
 
set_bit(HNS3_NIC_STATE_INITED, >state);
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
+   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
 
if (netif_msg_drv(handle))
hns3_info_show(priv);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 30ffaaf..427b72c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -18,6 +18,11 @@ struct hns3_sfp_type {
u8 ext_type;
 };
 
+struct hns3_pflag_desc {
+   char name[ETH_GSTRING_LEN];
+   void (*handler)(struct net_device *netdev, bool enable);
+};
+
 /* tqp related stats */
 #define HNS3_TQP_STAT(_string, _member){   \
.stats_string = _string,\
@@ -59,6 +64,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
 
+#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
+
 #define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
 
 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
@@ -394,6 +401,26 @@ static void hns3_self_test(struct net_device *ndev,
netif_dbg(h, drv, ndev, "self test end\n");
 }
 
+static void hns3_update_state(struct net_device *netdev,
+ enum hns3_nic_state state, bool enable)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+   if (enable)
+   set_bit(state, >state);
+   else
+   clear_bit(state, >state);
+}
+
+static void hns3_update_dim_state(struct net_device *netdev, bool enable)
+{
+   hns3_update_state(netdev, HNS3_NIC_STATE_DIM_ENABLE, enable);
+}
+
+static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
+   { "dim_enable", hns3_update_dim_state },
+};
+
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -410,6 +437,9 @@ static int hns3_get_sset_count(struct net_device *netdev, 
int stringset)
case ETH_SS_TEST:
return ops->get_sset_count(h, stringset);
 
+   case ETH_SS_PRIV_FLAGS:
+   return HNAE3_PFLAG_MAX;
+
default:
return -EOPNOTSUPP;
}
@@ -463,6 +493,7 @@ static void hns3_get_strings(struct net_device *netdev, u32 
stringset, u8 *data)
struct hnae3_handle *h = hns3_get_handle(netdev);
const struct hnae3_ae_ops *ops = h->ae_algo->ops;
char *buff = (char *)data;
+   int i;
 
if (!ops->get_strings)
return;
@@ -475,6 +506,13 @@ static void hns3_get_strings(struct net_device *netdev, 
u32 stringset, u8 *data)
case ETH_SS_TEST:
ops->get_strings(h, stringset, data);
break;
+   case ETH_SS_PRIV_FLAGS:
+   for (i = 0; i < HNS3_PRIV_FLAGS_LEN; i++) {
+   snprintf(buff, ETH_GSTRING_LEN, "%s",
+hns3_priv_flags[i].name);
+   buff += ETH_GSTRING_LEN;
+   }
+   break;
default:
break;
}
@@ -1516,6 +1554,35 @@ static int hns3_get_module_eeprom(struct net_device 
*netdev,
return ops->get_module_eeprom(handle, ee->offset, ee->len, data);

[PATCH V2 net-next 04/11] net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce

2020-11-08 Thread Huazhong Tan
Besides GL(Gap Limiting), QL(Quantity Limiting) can be modified
dynamically when DIM is supported. So rename gl_adapt_enable as
adapt_enable in struct hns3_enet_coalesce.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 12 ++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  8 
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 2813fe5..999a2aa 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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.
 */
@@ -273,8 +273,8 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
 *
 * Default: enable interrupt coalescing self-adaptive and GL
 */
-   tx_coal->gl_adapt_enable = 1;
-   rx_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;
@@ -3384,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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 4651ad1..8d33652 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -436,7 +436,7 @@ struct hns3_enet_coalesce {
u16 int_gl;
u16 int_ql;
u16 int_ql_max;
-   u8 gl_adapt_enable:1;
+   u8 adapt_enable:1;
u8 ql_enable:1;
u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 8d5c194..30ffaaf 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1105,9 +1105,9 @@ 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;
@@ -1268,9 +1268,9 @@ 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;
-- 
2.7.4



[PATCH V2 net-next 01/11] net: hns3: add support for configuring interrupt quantity limiting

2020-11-08 Thread Huazhong Tan
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 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 65 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 13 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 43 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/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 a362516..6e08719 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = >tqp_vector[i];
-   hns3_vector_gl_rl_init_hw(tqp_vector, priv);
+   hns3_

[PATCH net-next 06/11] net: hns3: add ethtool priv-flag for DIM

2020-11-06 Thread Huazhong Tan
Add a control private flag in ethtool for enable/disable
DIM feature.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  7 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 71 ++
 3 files changed, 79 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f9d4d23..18b3e43 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -716,6 +716,11 @@ struct hnae3_roce_private_info {
 #define HNAE3_UPE  (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
 #define HNAE3_MPE  (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
 
+enum hnae3_pflag {
+   HNAE3_PFLAG_DIM_ENABLE,
+   HNAE3_PFLAG_MAX
+};
+
 struct hnae3_handle {
struct hnae3_client *client;
struct pci_dev *pdev;
@@ -738,6 +743,8 @@ struct hnae3_handle {
 
/* Network interface message level enabled bits */
u32 msg_enable;
+
+   unsigned long priv_flags;
 };
 
 #define hnae3_set_field(origin, mask, shift, val) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 9e895b9..a567557 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4246,6 +4246,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
 
set_bit(HNS3_NIC_STATE_INITED, >state);
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
+   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
 
if (netif_msg_drv(handle))
hns3_info_show(priv);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 30ffaaf..427b72c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -18,6 +18,11 @@ struct hns3_sfp_type {
u8 ext_type;
 };
 
+struct hns3_pflag_desc {
+   char name[ETH_GSTRING_LEN];
+   void (*handler)(struct net_device *netdev, bool enable);
+};
+
 /* tqp related stats */
 #define HNS3_TQP_STAT(_string, _member){   \
.stats_string = _string,\
@@ -59,6 +64,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
 };
 
+#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
+
 #define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)
 
 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
@@ -394,6 +401,26 @@ static void hns3_self_test(struct net_device *ndev,
netif_dbg(h, drv, ndev, "self test end\n");
 }
 
+static void hns3_update_state(struct net_device *netdev,
+ enum hns3_nic_state state, bool enable)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+   if (enable)
+   set_bit(state, >state);
+   else
+   clear_bit(state, >state);
+}
+
+static void hns3_update_dim_state(struct net_device *netdev, bool enable)
+{
+   hns3_update_state(netdev, HNS3_NIC_STATE_DIM_ENABLE, enable);
+}
+
+static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
+   { "dim_enable", hns3_update_dim_state },
+};
+
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -410,6 +437,9 @@ static int hns3_get_sset_count(struct net_device *netdev, 
int stringset)
case ETH_SS_TEST:
return ops->get_sset_count(h, stringset);
 
+   case ETH_SS_PRIV_FLAGS:
+   return HNAE3_PFLAG_MAX;
+
default:
return -EOPNOTSUPP;
}
@@ -463,6 +493,7 @@ static void hns3_get_strings(struct net_device *netdev, u32 
stringset, u8 *data)
struct hnae3_handle *h = hns3_get_handle(netdev);
const struct hnae3_ae_ops *ops = h->ae_algo->ops;
char *buff = (char *)data;
+   int i;
 
if (!ops->get_strings)
return;
@@ -475,6 +506,13 @@ static void hns3_get_strings(struct net_device *netdev, 
u32 stringset, u8 *data)
case ETH_SS_TEST:
ops->get_strings(h, stringset, data);
break;
+   case ETH_SS_PRIV_FLAGS:
+   for (i = 0; i < HNS3_PRIV_FLAGS_LEN; i++) {
+   snprintf(buff, ETH_GSTRING_LEN, "%s",
+hns3_priv_flags[i].name);
+   buff += ETH_GSTRING_LEN;
+   }
+   break;
default:
break;
}
@@ -1516,6 +1554,35 @@ static int hns3_get_module_eeprom(struct net_device 
*netdev,
return ops->get_module_eeprom(handle, ee->offset, ee->len, data);

[PATCH net-next 04/11] net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce

2020-11-06 Thread Huazhong Tan
Besides GL(Gap Limiting), QL(Quantity Limiting) can be modified
dynamically when DIM is supported. So rename gl_adapt_enable as
adapt_enable in struct hns3_enet_coalesce.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 12 ++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  8 
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 2813fe5..999a2aa 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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.
 */
@@ -273,8 +273,8 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
 *
 * Default: enable interrupt coalescing self-adaptive and GL
 */
-   tx_coal->gl_adapt_enable = 1;
-   rx_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;
@@ -3384,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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 4651ad1..8d33652 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -436,7 +436,7 @@ struct hns3_enet_coalesce {
u16 int_gl;
u16 int_ql;
u16 int_ql_max;
-   u8 gl_adapt_enable:1;
+   u8 adapt_enable:1;
u8 ql_enable:1;
u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 8d5c194..30ffaaf 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1105,9 +1105,9 @@ 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;
@@ -1268,9 +1268,9 @@ 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;
-- 
2.7.4



[PATCH net-next 08/11] net: hns3: add a check for ethtool priv-flag interface

2020-11-06 Thread Huazhong Tan
Add a check for hns3_set_priv_flags() since if the capability
is unsupported its private flags should not be modified as well.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 19 +++
 3 files changed, 21 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 18b3e43..3642740 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -744,6 +744,7 @@ struct hnae3_handle {
/* Network interface message level enabled bits */
u32 msg_enable;
 
+   unsigned long supported_pflags;
unsigned long priv_flags;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index f686723..c30cf9e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4152,6 +4152,7 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_INITED, >state);
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+   set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
 }
 
 static int hns3_client_init(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 427b72c..6904c0a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1561,12 +1561,31 @@ static u32 hns3_get_priv_flags(struct net_device 
*netdev)
return handle->priv_flags;
 }
 
+static int hns3_check_priv_flags(struct hnae3_handle *h, u32 changed)
+{
+   u32 i;
+
+   for (i = 0; i < HNAE3_PFLAG_MAX; i++)
+   if ((changed & BIT(i)) && !test_bit(i, >supported_pflags)) {
+   netdev_err(h->netdev, "%s is unsupported\n",
+  hns3_priv_flags[i].name);
+   return -EOPNOTSUPP;
+   }
+
+   return 0;
+}
+
 static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
 {
struct hnae3_handle *handle = hns3_get_handle(netdev);
u32 changed = pflags ^ handle->priv_flags;
+   int ret;
u32 i;
 
+   ret = hns3_check_priv_flags(handle, changed);
+   if (ret)
+   return ret;
+
for (i = 0; i < HNAE3_PFLAG_MAX; i++) {
if (changed & BIT(i)) {
bool enable = !(handle->priv_flags & BIT(i));
-- 
2.7.4



[PATCH net-next 10/11] net: hns3: add ethtool priv-flag for EQ/CQ

2020-11-06 Thread Huazhong Tan
Add a control private flag in ethtool for switching EQ/CQ mode.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  2 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 19 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 23 ++
 4 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 345e8a4..a452874 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -719,6 +719,8 @@ struct hnae3_roce_private_info {
 
 enum hnae3_pflag {
HNAE3_PFLAG_DIM_ENABLE,
+   HNAE3_PFLAG_TX_CQE_MODE,
+   HNAE3_PFLAG_RX_CQE_MODE,
HNAE3_PFLAG_MAX
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index d1243ea..93f7731 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4144,6 +4144,7 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
 
 static void hns3_state_init(struct hnae3_handle *handle)
 {
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev);
 
@@ -4151,10 +4152,24 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
+
+   /* device version above V3(include V3), GL can switch CQ/EQ period
+* mode.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+   set_bit(HNAE3_PFLAG_TX_CQE_MODE, >supported_pflags);
+   set_bit(HNAE3_PFLAG_RX_CQE_MODE, >supported_pflags);
+   }
+
+   if (priv->tx_cqe_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
+   handle->priv_flags |= BIT(HNAE3_PFLAG_TX_CQE_MODE);
+
+   if (priv->rx_cqe_mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE)
+   handle->priv_flags |= BIT(HNAE3_PFLAG_RX_CQE_MODE);
 }
 
-static void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
-   enum dim_cq_period_mode mode, bool is_tx)
+void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode mode, bool is_tx)
 {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
struct hnae3_handle *handle = priv->ae_handle;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index c6c082a..ecdb544 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -635,4 +635,6 @@ void hns3_dbg_uninit(struct hnae3_handle *handle);
 void hns3_dbg_register_debugfs(const char *debugfs_dir_name);
 void hns3_dbg_unregister_debugfs(void);
 void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size);
+void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode mode, bool is_tx);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 6904c0a..8de2789 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -417,8 +417,31 @@ static void hns3_update_dim_state(struct net_device 
*netdev, bool enable)
hns3_update_state(netdev, HNS3_NIC_STATE_DIM_ENABLE, enable);
 }
 
+static void hns3_update_cqe_mode(struct net_device *netdev, bool enable, bool 
is_tx)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+   enum dim_cq_period_mode mode;
+
+   mode = enable ? DIM_CQ_PERIOD_MODE_START_FROM_CQE :
+   DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+
+   hns3_set_cq_period_mode(priv, mode, is_tx);
+}
+
+static void hns3_update_tx_cqe_mode(struct net_device *netdev, bool enable)
+{
+   hns3_update_cqe_mode(netdev, enable, true);
+}
+
+static void hns3_update_rx_cqe_mode(struct net_device *netdev, bool enable)
+{
+   hns3_update_cqe_mode(netdev, enable, false);
+}
+
 static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
{ "dim_enable", hns3_update_dim_state },
+   { "tx_cqe_mode",hns3_update_tx_cqe_mode },
+   { "rx_cqe_mode",hns3_update_rx_cqe_mode },
 };
 
 static int hns3_get_sset_count(struct net_device *netdev, int stringset)
-- 
2.7.4



[PATCH net-next 01/11] net: hns3: add support for configuring interrupt quantity limiting

2020-11-06 Thread Huazhong Tan
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 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 65 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 13 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 43 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/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 a362516..6e08719 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = _vector->tx_group.coal;
+   struct hns3_enet_coalesce *rx_coal = _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 = >tqp_vector[i];
-   hns3_vector_gl_rl_init_hw(tqp_vector, priv);
+   hns3_

[PATCH net-next 00/11] net: hns3: updates for -next

2020-11-06 Thread Huazhong Tan
There are several updates relating to the interrupt coalesce for
the HNS3 ethernet driver.

#1 adds support for QL(quantity limiting, interrupt coalesce
   based on the frame quantity).
#2 adds support for 1us unit GL(gap limiting, interrupt coalesce
   based on the gap time).
#3 queries the maximum value of GL from the firmware instead of
   a fixed value in code.
#4 renames gl_adapt_enable in struct hns3_enet_coalesce to fit
   its new usage.
#5 & #6 adds support for the dynamic interrupt moderation,
   and adds a control private flag in ethtool.
#7 adds wrapper function for state initialization.
#8 adds a check for the read-only private flag.
#9 & #10 adds support for EQ/CQ configuration, and adds a control
   private flag in ethtool.
#11 adds debugfs support for interrupt coalesce.

Huazhong Tan (11):
  net: hns3: add support for configuring interrupt quantity limiting
  net: hns3: add support for 1us unit GL configuration
  net: hns3: add support for querying maximum value of GL
  net: hns3: rename gl_adapt_enable in struct hns3_enet_coalesce
  net: hns3: add support for dynamic interrupt moderation
  net: hns3: add ethtool priv-flag for DIM
  net: hns3: add hns3_state_init() to do state initialization
  net: hns3: add a check for ethtool priv-flag interface
  net: hns3: add support for EQ/CQ mode configuration
  net: hns3: add ethtool priv-flag for EQ/CQ
  net: hns3: add debugfs support for interrupt coalesce

 drivers/net/ethernet/hisilicon/Kconfig |   1 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  12 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 125 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 258 ++---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  31 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 184 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   8 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|   8 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |   8 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |   8 +
 10 files changed, 604 insertions(+), 39 deletions(-)

-- 
2.7.4



[PATCH net-next 07/11] net: hns3: add hns3_state_init() to do state initialization

2020-11-06 Thread Huazhong Tan
To improve the readability and maintainability, add hns3_state_init()
to initialize the state.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a567557..f686723 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -4144,6 +4144,16 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
dev_info(priv->dev, "Max mtu size: %u\n", priv->netdev->max_mtu);
 }
 
+static void hns3_state_init(struct hnae3_handle *handle)
+{
+   struct net_device *netdev = handle->kinfo.netdev;
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+
+   set_bit(HNS3_NIC_STATE_INITED, >state);
+   set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
+   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
struct pci_dev *pdev = handle->pdev;
@@ -4244,9 +4254,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
/* MTU range: (ETH_MIN_MTU(kernel default) - 9702) */
netdev->max_mtu = HNS3_MAX_MTU;
 
-   set_bit(HNS3_NIC_STATE_INITED, >state);
-   set_bit(HNS3_NIC_STATE_DIM_ENABLE, >state);
-   handle->priv_flags |= BIT(HNAE3_PFLAG_DIM_ENABLE);
+   hns3_state_init(handle);
 
if (netif_msg_drv(handle))
hns3_info_show(priv);
-- 
2.7.4



[PATCH net-next 11/11] net: hns3: add debugfs support for interrupt coalesce

2020-11-06 Thread Huazhong Tan
Since user may need to check the current configuration of the
interrupt coalesce, so add debugfs support for query this info,
which includes DIM profile, coalesce configuration of both software
and hardware.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 124 +
 1 file changed, 124 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index a5ebca8..1efeed6 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -12,6 +12,91 @@
 
 static struct dentry *hns3_dbgfs_root;
 
+static ssize_t hns3_dbg_coal_write(struct file *filp, const char __user 
*buffer,
+  size_t count, loff_t *ppos)
+{
+   struct hnae3_handle *h = filp->private_data;
+   struct hns3_nic_priv *priv  = h->priv;
+   struct hns3_enet_tqp_vector *tqp_vector;
+   struct hns3_enet_coalesce *coal;
+   int uncopied_bytes;
+   unsigned int idx;
+   struct dim *dim;
+   char *cmd_buf;
+
+   if (*ppos != 0)
+   return 0;
+
+   if (!test_bit(HNS3_NIC_STATE_INITED, >state)) {
+   dev_err(>pdev->dev, "device is not initialized\n");
+   return -EFAULT;
+   }
+
+   cmd_buf = kzalloc(count + 1, GFP_KERNEL);
+   if (!cmd_buf)
+   return -ENOMEM;
+
+   uncopied_bytes = copy_from_user(cmd_buf, buffer, count);
+   if (uncopied_bytes) {
+   kfree(cmd_buf);
+   return -EFAULT;
+   }
+
+   cmd_buf[count] = '\0';
+
+   if (kstrtouint(cmd_buf, 0, ))
+   idx = 0;
+
+   if (idx >= priv->vector_num) {
+   dev_err(>pdev->dev,
+   "vector index(%u) is out of range(0-%u)\n", idx,
+   priv->vector_num - 1);
+   kfree(cmd_buf);
+   return -EINVAL;
+   }
+
+   tqp_vector = >tqp_vector[idx];
+   coal = _vector->tx_group.coal;
+   dim = _vector->tx_group.dim;
+
+   dev_info(>pdev->dev, "vector[%u] interrupt coalesce info:\n", idx);
+   dev_info(>pdev->dev,
+"TX DIM info state = %d profile_ix = %d mode = %d tune_state = 
%d steps_right = %d steps_left = %d tired = %d\n",
+dim->state, dim->profile_ix, dim->mode, dim->tune_state,
+dim->steps_right, dim->steps_left, dim->tired);
+
+   dev_info(>pdev->dev, "TX GL info sw_gl = %u, hw_gl = %u\n",
+coal->int_gl,
+readl(tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET));
+
+   if (coal->ql_enable)
+   dev_info(>pdev->dev, "TX QL info sw_ql = %u, hw_ql = %u\n",
+coal->int_ql,
+readl(tqp_vector->mask_addr + 
HNS3_VECTOR_TX_QL_OFFSET));
+
+   coal = _vector->rx_group.coal;
+   dim = _vector->rx_group.dim;
+
+   dev_info(>pdev->dev,
+"RX dim_info state = %d profile_ix = %d mode = %d tune_state = 
%d steps_right = %d steps_left = %d tired = %d\n",
+dim->state, dim->profile_ix, dim->mode, dim->tune_state,
+dim->steps_right, dim->steps_left, dim->tired);
+
+   dev_info(>pdev->dev, "RX GL info sw_gl = %u, hw_gl = %u\n",
+coal->int_gl,
+readl(tqp_vector->mask_addr + HNS3_VECTOR_GL0_OFFSET));
+
+   if (coal->ql_enable)
+   dev_info(>pdev->dev, "RX QL info sw_ql = %u, hw_ql = %u\n",
+coal->int_ql,
+readl(tqp_vector->mask_addr + 
HNS3_VECTOR_RX_QL_OFFSET));
+
+   kfree(cmd_buf);
+   cmd_buf = NULL;
+
+   return count;
+}
+
 static int hns3_dbg_queue_info(struct hnae3_handle *h,
   const char *cmd_buf)
 {
@@ -352,6 +437,35 @@ static void hns3_dbg_dev_specs(struct hnae3_handle *h)
dev_info(priv->dev, "MAX INT GL: %u\n", dev_specs->max_int_gl);
 }
 
+static ssize_t hns3_dbg_coal_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+   int uncopy_bytes;
+   char *buf;
+   int len;
+
+   if (*ppos != 0)
+   return 0;
+
+   if (count < HNS3_DBG_READ_LEN)
+   return -ENOSPC;
+
+   buf = kzalloc(HNS3_DBG_READ_LEN, GFP_KERNEL);
+   if (!buf)
+   return -ENOMEM;
+
+   len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n",
+   "Please echo index to coal");
+   uncopy_bytes = copy_to_user(buffer, buf, len);
+
+   kfree(buf);
+
+   if (uncopy_bytes)
+   return -EFAULT;
+

[PATCH net-next 09/11] net: hns3: add support for EQ/CQ mode configuration

2020-11-06 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL can
select EQ or CQ mode, so adds support for it.

In CQ mode, the coalesced timer will restart upon new completion,
while in EQ mode, the timer will not restart.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 49 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  8 
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  1 +
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  1 +
 5 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 3642740..345e8a4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -684,6 +684,7 @@ struct hnae3_knic_private_info {
 
u16 int_rl_setting;
enum pkt_hash_types rss_type;
+   void __iomem *io_base;
 };
 
 struct hnae3_roce_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index c30cf9e..d1243ea 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3653,9 +3653,7 @@ static void hns3_tx_dim_work(struct work_struct *work)
 static void hns3_nic_init_dim(struct hns3_enet_tqp_vector *tqp_vector)
 {
INIT_WORK(_vector->rx_group.dim.work, hns3_rx_dim_work);
-   tqp_vector->rx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
INIT_WORK(_vector->tx_group.dim.work, hns3_tx_dim_work);
-   tqp_vector->tx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 }
 
 static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
@@ -4155,6 +4153,48 @@ static void hns3_state_init(struct hnae3_handle *handle)
set_bit(HNAE3_PFLAG_DIM_ENABLE, >supported_pflags);
 }
 
+static void hns3_set_cq_period_mode(struct hns3_nic_priv *priv,
+   enum dim_cq_period_mode mode, bool is_tx)
+{
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
+   struct hnae3_handle *handle = priv->ae_handle;
+   int i;
+
+   if (is_tx) {
+   priv->tx_cqe_mode = mode;
+
+   for (i = 0; i < priv->vector_num; i++)
+   priv->tqp_vector[i].tx_group.dim.mode = mode;
+   } else {
+   priv->rx_cqe_mode = mode;
+
+   for (i = 0; i < priv->vector_num; i++)
+   priv->tqp_vector[i].rx_group.dim.mode = mode;
+   }
+
+   /* only device version above V3(include V3), GL can switch CQ/EQ
+* period mode.
+*/
+   if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+   u32 new_mode;
+   u64 reg;
+
+   new_mode = (mode == DIM_CQ_PERIOD_MODE_START_FROM_CQE) ?
+   HNS3_CQ_MODE_CQE : HNS3_CQ_MODE_EQE;
+   reg = is_tx ? HNS3_GL1_CQ_MODE_REG : HNS3_GL0_CQ_MODE_REG;
+
+   writel(new_mode, handle->kinfo.io_base + reg);
+   }
+}
+
+static void hns3_cq_period_mode_init(struct hns3_nic_priv *priv,
+enum dim_cq_period_mode tx_mode,
+enum dim_cq_period_mode rx_mode)
+{
+   hns3_set_cq_period_mode(priv, tx_mode, true);
+   hns3_set_cq_period_mode(priv, rx_mode, false);
+}
+
 static int hns3_client_init(struct hnae3_handle *handle)
 {
struct pci_dev *pdev = handle->pdev;
@@ -4220,6 +4260,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_init_ring;
}
 
+   hns3_cq_period_mode_init(priv, DIM_CQ_PERIOD_MODE_START_FROM_EQE,
+DIM_CQ_PERIOD_MODE_START_FROM_EQE);
+
ret = hns3_init_phy(netdev);
if (ret)
goto out_init_phy;
@@ -4580,6 +4623,8 @@ static int hns3_reset_notify_init_enet(struct 
hnae3_handle *handle)
if (ret)
goto err_uninit_vector;
 
+   hns3_cq_period_mode_init(priv, priv->tx_cqe_mode, priv->rx_cqe_mode);
+
/* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(netdev);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index eb4e7ef..c6c082a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -188,6 +188,12 @@ enum hns3_nic_state {
 
 #define HNS3_RING_EN_B 0
 
+#define HNS3_GL0_CQ_MODE_REG   0x20d00
+#define HNS3_GL1_CQ_MODE_REG   0x20d04
+#define HNS3_GL2_CQ_MODE_REG   0x20d08
+#define HNS3_CQ_MODE_EQE   1U
+#define HNS3_CQ_MODE_CQE

[PATCH net-next 05/11] net: hns3: add support for dynamic interrupt moderation

2020-11-06 Thread Huazhong Tan
Add dynamic interrupt moderation support for the HNS3 driver.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/Kconfig  |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 87 -
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h |  4 ++
 3 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 44f9279..fa6025d 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -130,6 +130,7 @@ config HNS3_ENET
default m
depends on 64BIT && PCI
depends on INET
+   select DIMLIB
help
  This selects the Ethernet Driver for Hisilicon Network Subsystem 3 
for hip08
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 999a2aa..9e895b9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -96,6 +96,7 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
struct hns3_enet_tqp_vector *tqp_vector = vector;
 
napi_schedule_irqoff(_vector->napi);
+   tqp_vector->event_cnt++;
 
return IRQ_HANDLED;
 }
@@ -199,6 +200,8 @@ static void hns3_vector_disable(struct hns3_enet_tqp_vector 
*tqp_vector)
 
disable_irq(tqp_vector->vector_irq);
napi_disable(_vector->napi);
+   cancel_work_sync(_vector->rx_group.dim.work);
+   cancel_work_sync(_vector->tx_group.dim.work);
 }
 
 void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
@@ -3401,6 +3404,32 @@ static void hns3_update_new_int_gl(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->last_jiffies = jiffies;
 }
 
+static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *rx_group = _vector->rx_group;
+   struct dim_sample sample = {};
+
+   if (!rx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, rx_group->total_packets,
+ rx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
+static void hns3_update_tx_int_coalesce(struct hns3_enet_tqp_vector 
*tqp_vector)
+{
+   struct hns3_enet_ring_group *tx_group = _vector->tx_group;
+   struct dim_sample sample = {};
+
+   if (!tx_group->coal.adapt_enable)
+   return;
+
+   dim_update_sample(tqp_vector->event_cnt, tx_group->total_packets,
+ tx_group->total_bytes, );
+   net_dim(_group->dim, sample);
+}
+
 static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
 {
struct hns3_nic_priv *priv = netdev_priv(napi->dev);
@@ -3444,7 +3473,13 @@ static int hns3_nic_common_poll(struct napi_struct 
*napi, int budget)
 
if (napi_complete(napi) &&
likely(!test_bit(HNS3_NIC_STATE_DOWN, >state))) {
-   hns3_update_new_int_gl(tqp_vector);
+   if (test_bit(HNS3_NIC_STATE_DIM_ENABLE, >state)) {
+   hns3_update_rx_int_coalesce(tqp_vector);
+   hns3_update_tx_int_coalesce(tqp_vector);
+   } else {
+   hns3_update_new_int_gl(tqp_vector);
+   }
+
hns3_mask_vector_irq(tqp_vector, 1);
}
 
@@ -3575,6 +3610,54 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv 
*priv)
}
 }
 
+static void hns3_rx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+
+   hns3_set_vector_coalesce_rx_gl(group->ring->tqp_vector, cur_moder.usec);
+   tqp_vector->rx_group.coal.int_gl = cur_moder.usec;
+
+   if (cur_moder.pkts < tqp_vector->rx_group.coal.int_ql_max) {
+   hns3_set_vector_coalesce_rx_ql(tqp_vector, cur_moder.pkts);
+   tqp_vector->rx_group.coal.int_ql = cur_moder.pkts;
+   }
+
+   dim->state = DIM_START_MEASURE;
+}
+
+static void hns3_tx_dim_work(struct work_struct *work)
+{
+   struct dim *dim = container_of(work, struct dim, work);
+   struct hns3_enet_ring_group *group = container_of(dim,
+   struct hns3_enet_ring_group, dim);
+   struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
+   struct dim_cq_moder cur_moder =
+   net_dim_get_tx_moderation(dim->mode, dim->profile_ix);

[PATCH net-next 03/11] net: hns3: add support for querying maximum value of GL

2020-11-06 Thread Huazhong Tan
For maintainability and compatibility, add support for querying
the maximum value of GL.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h   |  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c|  1 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h   |  1 -
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c| 14 --
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h|  8 
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c   |  6 ++
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h  |  8 
 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c |  6 ++
 8 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 912c51e..f9d4d23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -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 */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index dc9a857..a5ebca8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -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,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index b37635d..4651ad1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -420,7 +420,6 @@ enum hns3_flow_level_range {
HNS3_FLOW_ULTRA = 3,
 };
 
-#define HNS3_INT_GL_MAX0x1FE0
 #define HNS3_INT_GL_50K0x0014
 #define HNS3_INT_GL_20K0x0032
 #define HNS3_INT_GL_18K0x0036
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 128e9ec..8d5c194 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1130,19 +1130,21 @@ 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;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 096e26a..5b7967c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -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)
 {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hn

[PATCH net-next 02/11] net: hns3: add support for 1us unit GL configuration

2020-11-06 Thread Huazhong Tan
For device whose version is above V3(include V3), the GL
configuration can set as 1us unit, so adds support for
configuring this field.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 26 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  3 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  6 +
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 6e08719..2813fe5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -224,17 +224,27 @@ 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(tx_gl_reg, tqp_vector->mask_addr + HNS3_VECTOR_GL1_OFFSET);
+   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,
@@ -272,6 +282,14 @@ static void hns3_vector_coalesce_init(struct 
hns3_enet_tqp_vector *tqp_vector,
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;
+   }
+
if (ae_dev->dev_specs.int_ql_max) {
tx_coal->ql_enable = 1;
rx_coal->ql_enable = 1;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 10990bd..b37635d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -426,6 +426,8 @@ enum hns3_flow_level_range {
 #define HNS3_INT_GL_18K0x0036
 #define HNS3_INT_GL_8K 0x007C
 
+#define HNS3_INT_GL_1USBIT(31)
+
 #define HNS3_INT_RL_MAX0x00EC
 #define HNS3_INT_RL_ENABLE_MASK0x40
 
@@ -437,6 +439,7 @@ struct hns3_enet_coalesce {
u16 int_ql_max;
u8 gl_adapt_enable:1;
u8 ql_enable:1;
+   u8 unit_1us:1;
enum hns3_flow_level_range flow_level;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 9af7cb9..128e9ec 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1146,6 +1146,12 @@ static int hns3_check_gl_coalesce_para(struct net_device 
*netdev,
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,
-- 
2.7.4



[PATCH net-next 0/7] net: hns3: updates for -next

2020-09-29 Thread Huazhong Tan
There are some misc updates for the HNS3 ethernet driver.
#1 uses the queried BD number as the limit for TSO.
#2 renames trace event hns3_over_8bd since #1.
#3 adds UDP segmentation offload support.
#4 adds RoCE VF reset support.
#5 is a minor cleanup.
#6 & #7 add debugfs for device specifications and TQP enable status.

Guangbin Huang (2):
  net: hns3: debugfs add new command to query device specifications
  net: hns3: dump tqp enable status in debugfs

Guojia Liao (1):
  net: hns3: remove unused code in hns3_self_test()

Huazhong Tan (4):
  net: hns3: replace macro HNS3_MAX_NON_TSO_BD_NUM
  net: hns3: rename trace event hns3_over_8bd
  net: hns3: add UDP segmentation offload support
  net: hns3: Add RoCE VF reset support

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  3 +
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 50 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 71 ++
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  8 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  9 +--
 drivers/net/ethernet/hisilicon/hns3/hns3_trace.h   |  2 +-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 50 +++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |  1 +
 8 files changed, 157 insertions(+), 37 deletions(-)

-- 
2.7.4



[PATCH net-next 5/7] net: hns3: remove unused code in hns3_self_test()

2020-09-29 Thread Huazhong Tan
From: Guojia Liao 

NETIF_F_HW_VLAN_CTAG_FILTER is not set in netdev->hw_feature,
but set in netdev->features.

So the handler of NETIF_F_HW_VLAN_CTAG_FILTER in hns3_self_test() is
always true, remove it.

Signed-off-by: Guojia Liao 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index bf3504d..6b07b27 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -311,9 +311,6 @@ static void hns3_self_test(struct net_device *ndev,
struct hnae3_handle *h = priv->ae_handle;
int st_param[HNS3_SELF_TEST_TYPE_NUM][2];
bool if_running = netif_running(ndev);
-#if IS_ENABLED(CONFIG_VLAN_8021Q)
-   bool dis_vlan_filter;
-#endif
int test_index = 0;
u32 i;
 
@@ -350,9 +347,7 @@ static void hns3_self_test(struct net_device *ndev,
 
 #if IS_ENABLED(CONFIG_VLAN_8021Q)
/* Disable the vlan filter for selftest does not support it */
-   dis_vlan_filter = (ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
-   h->ae_algo->ops->enable_vlan_filter;
-   if (dis_vlan_filter)
+   if (h->ae_algo->ops->enable_vlan_filter)
h->ae_algo->ops->enable_vlan_filter(h, false);
 #endif
 
@@ -389,7 +384,7 @@ static void hns3_self_test(struct net_device *ndev,
h->ae_algo->ops->halt_autoneg(h, false);
 
 #if IS_ENABLED(CONFIG_VLAN_8021Q)
-   if (dis_vlan_filter)
+   if (h->ae_algo->ops->enable_vlan_filter)
h->ae_algo->ops->enable_vlan_filter(h, true);
 #endif
 
-- 
2.7.4



[PATCH net-next 7/7] net: hns3: dump tqp enable status in debugfs

2020-09-29 Thread Huazhong Tan
From: Guangbin Huang 

Adds debugfs to dump tqp enable status.

Signed-off-by: Guangbin Huang 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  3 +++
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 22 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h|  2 ++
 3 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index f6d0702..912c51e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -130,6 +130,9 @@ enum HNAE3_DEV_CAP_BITS {
 #define hnae3_dev_stash_supported(hdev) \
test_bit(HNAE3_DEV_SUPPORT_STASH_B, (hdev)->ae_dev->caps)
 
+#define hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev) \
+   test_bit(HNAE3_DEV_SUPPORT_TQP_TXRX_INDEP_B, (ae_dev)->caps)
+
 #define ring_ptr_move_fw(ring, p) \
((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
 #define ring_ptr_move_bw(ring, p) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index d6f8817..dc9a857 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -15,6 +15,7 @@ static struct dentry *hns3_dbgfs_root;
 static int hns3_dbg_queue_info(struct hnae3_handle *h,
   const char *cmd_buf)
 {
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
struct hns3_nic_priv *priv = h->priv;
struct hns3_enet_ring *ring;
u32 base_add_l, base_add_h;
@@ -118,8 +119,25 @@ static int hns3_dbg_queue_info(struct hnae3_handle *h,
 
value = readl_relaxed(ring->tqp->io_base +
  HNS3_RING_TX_RING_PKTNUM_RECORD_REG);
-   dev_info(>pdev->dev, "TX(%u) RING PKTNUM: %u\n\n", i,
-value);
+   dev_info(>pdev->dev, "TX(%u) RING PKTNUM: %u\n", i, value);
+
+   value = readl_relaxed(ring->tqp->io_base + HNS3_RING_EN_REG);
+   dev_info(>pdev->dev, "TX/RX(%u) RING EN: %s\n", i,
+value ? "enable" : "disable");
+
+   if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) {
+   value = readl_relaxed(ring->tqp->io_base +
+ HNS3_RING_TX_EN_REG);
+   dev_info(>pdev->dev, "TX(%u) RING EN: %s\n", i,
+value ? "enable" : "disable");
+
+   value = readl_relaxed(ring->tqp->io_base +
+ HNS3_RING_RX_EN_REG);
+   dev_info(>pdev->dev, "RX(%u) RING EN: %s\n", i,
+value ? "enable" : "disable");
+   }
+
+   dev_info(>pdev->dev, "\n");
}
 
return 0;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 35b0375..1c81dea 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -43,6 +43,8 @@ enum hns3_nic_state {
 #define HNS3_RING_TX_RING_EBD_OFFSET_REG   0x00070
 #define HNS3_RING_TX_RING_BD_ERR_REG   0x00074
 #define HNS3_RING_EN_REG   0x00090
+#define HNS3_RING_RX_EN_REG0x00098
+#define HNS3_RING_TX_EN_REG0x000D4
 
 #define HNS3_RX_HEAD_SIZE  256
 
-- 
2.7.4



[PATCH net-next 1/7] net: hns3: replace macro HNS3_MAX_NON_TSO_BD_NUM

2020-09-29 Thread Huazhong Tan
Currently, the driver is able to query the device's specifications,
which includes the maximum BD number of non TSO packet, so replace
macro HNS3_MAX_NON_TSO_BD_NUM with the queried value, and rewrite
macro HNS3_MAX_NON_TSO_SIZE whose value depends on the the maximum
BD number of non TSO packet.

Also, add a new parameter max_non_tso_bd_num to function
hns3_tx_bd_num() and hns3_skb_need_linearized(), then they can get
the maximum BD number of non TSO packet from the caller instead of
calculating by themself, The note of hns3_skb_need_linearized()
should be update as well.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 47 +++--
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h |  6 ++--
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 1c4e820e..a393755 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1184,21 +1184,23 @@ static unsigned int hns3_skb_bd_num(struct sk_buff 
*skb, unsigned int *bd_size,
return bd_num;
 }
 
-static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size)
+static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size,
+  u8 max_non_tso_bd_num)
 {
struct sk_buff *frag_skb;
unsigned int bd_num = 0;
 
/* If the total len is within the max bd limit */
if (likely(skb->len <= HNS3_MAX_BD_SIZE && !skb_has_frag_list(skb) &&
-  skb_shinfo(skb)->nr_frags < HNS3_MAX_NON_TSO_BD_NUM))
+  skb_shinfo(skb)->nr_frags < max_non_tso_bd_num))
return skb_shinfo(skb)->nr_frags + 1U;
 
/* The below case will always be linearized, return
 * HNS3_MAX_BD_NUM_TSO + 1U to make sure it is linearized.
 */
if (unlikely(skb->len > HNS3_MAX_TSO_SIZE ||
-(!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE)))
+(!skb_is_gso(skb) && skb->len >
+ HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num
return HNS3_MAX_TSO_BD_NUM + 1U;
 
bd_num = hns3_skb_bd_num(skb, bd_size, bd_num);
@@ -1223,31 +1225,34 @@ static unsigned int hns3_gso_hdr_len(struct sk_buff 
*skb)
return skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb);
 }
 
-/* HW need every continuous 8 buffer data to be larger than MSS,
- * we simplify it by ensuring skb_headlen + the first continuous
- * 7 frags to to be larger than gso header len + mss, and the remaining
- * continuous 7 frags to be larger than MSS except the last 7 frags.
+/* HW need every continuous max_non_tso_bd_num buffer data to be larger
+ * than MSS, we simplify it by ensuring skb_headlen + the first continuous
+ * max_non_tso_bd_num - 1 frags to be larger than gso header len + mss,
+ * and the remaining continuous max_non_tso_bd_num - 1 frags to be larger
+ * than MSS except the last max_non_tso_bd_num - 1 frags.
  */
 static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int 
*bd_size,
-unsigned int bd_num)
+unsigned int bd_num, u8 max_non_tso_bd_num)
 {
unsigned int tot_len = 0;
int i;
 
-   for (i = 0; i < HNS3_MAX_NON_TSO_BD_NUM - 1U; i++)
+   for (i = 0; i < max_non_tso_bd_num - 1U; i++)
tot_len += bd_size[i];
 
-   /* ensure the first 8 frags is greater than mss + header */
-   if (tot_len + bd_size[HNS3_MAX_NON_TSO_BD_NUM - 1U] <
+   /* ensure the first max_non_tso_bd_num frags is greater than
+* mss + header
+*/
+   if (tot_len + bd_size[max_non_tso_bd_num - 1U] <
skb_shinfo(skb)->gso_size + hns3_gso_hdr_len(skb))
return true;
 
-   /* ensure every continuous 7 buffer is greater than mss
-* except the last one.
+   /* ensure every continuous max_non_tso_bd_num - 1 buffer is greater
+* than mss except the last one.
 */
-   for (i = 0; i < bd_num - HNS3_MAX_NON_TSO_BD_NUM; i++) {
+   for (i = 0; i < bd_num - max_non_tso_bd_num; i++) {
tot_len -= bd_size[i];
-   tot_len += bd_size[i + HNS3_MAX_NON_TSO_BD_NUM - 1U];
+   tot_len += bd_size[i + max_non_tso_bd_num - 1U];
 
if (tot_len < skb_shinfo(skb)->gso_size)
return true;
@@ -1269,13 +1274,15 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring 
*ring,
  struct sk_buff *skb)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
+   u8 max_non_tso_bd_num = priv->max_non_tso_bd_num;
unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U];
unsigned int bd_num;
 

[PATCH net-next 4/7] net: hns3: Add RoCE VF reset support

2020-09-29 Thread Huazhong Tan
Add RoCE VF client reset support by notifying the RoCE VF client
when hns3 VF is resetting and adding a interface to query whether
CMDQ is ready to work.

Signed-off-by: Huazhong Tan 
---
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  | 50 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h  |  1 +
 2 files changed, 51 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 8c8e666..50c84c5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -1702,6 +1702,26 @@ static int hclgevf_notify_client(struct hclgevf_dev 
*hdev,
return ret;
 }
 
+static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev,
+ enum hnae3_reset_notify_type type)
+{
+   struct hnae3_client *client = hdev->roce_client;
+   struct hnae3_handle *handle = >roce;
+   int ret;
+
+   if (!test_bit(HCLGEVF_STATE_ROCE_REGISTERED, >state) || !client)
+   return 0;
+
+   if (!client->ops->reset_notify)
+   return -EOPNOTSUPP;
+
+   ret = client->ops->reset_notify(handle, type);
+   if (ret)
+   dev_err(>pdev->dev, "notify roce client failed %d(%d)",
+   type, ret);
+   return ret;
+}
+
 static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
 {
 #define HCLGEVF_RESET_WAIT_US  2
@@ -1865,6 +1885,11 @@ static int hclgevf_reset_prepare(struct hclgevf_dev 
*hdev)
 
hdev->rst_stats.rst_cnt++;
 
+   /* perform reset of the stack & ae device for a client */
+   ret = hclgevf_notify_roce_client(hdev, HNAE3_DOWN_CLIENT);
+   if (ret)
+   return ret;
+
rtnl_lock();
/* bring down the nic to stop any ongoing TX/RX */
ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
@@ -1880,6 +1905,9 @@ static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev)
int ret;
 
hdev->rst_stats.hw_rst_done_cnt++;
+   ret = hclgevf_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT);
+   if (ret)
+   return ret;
 
rtnl_lock();
/* now, re-initialize the nic client and ae device */
@@ -1890,6 +1918,18 @@ static int hclgevf_reset_rebuild(struct hclgevf_dev 
*hdev)
return ret;
}
 
+   ret = hclgevf_notify_roce_client(hdev, HNAE3_INIT_CLIENT);
+   /* ignore RoCE notify error if it fails HCLGEVF_RESET_MAX_FAIL_CNT - 1
+* times
+*/
+   if (ret &&
+   hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT - 1)
+   return ret;
+
+   ret = hclgevf_notify_roce_client(hdev, HNAE3_UP_CLIENT);
+   if (ret)
+   return ret;
+
hdev->last_reset_time = jiffies;
hdev->rst_stats.rst_done_cnt++;
hdev->rst_stats.rst_fail_cnt = 0;
@@ -2757,6 +2797,7 @@ static int hclgevf_init_roce_client_instance(struct 
hnae3_ae_dev *ae_dev,
if (ret)
return ret;
 
+   set_bit(HCLGEVF_STATE_ROCE_REGISTERED, >state);
hnae3_set_client_init_flag(client, ae_dev, 1);
 
return 0;
@@ -2817,6 +2858,7 @@ static void hclgevf_uninit_client_instance(struct 
hnae3_client *client,
 
/* un-init roce, if it exists */
if (hdev->roce_client) {
+   clear_bit(HCLGEVF_STATE_ROCE_REGISTERED, >state);
hdev->roce_client->ops->uninit_instance(>roce, 0);
hdev->roce_client = NULL;
hdev->roce.client = NULL;
@@ -3419,6 +3461,13 @@ static bool hclgevf_get_hw_reset_stat(struct 
hnae3_handle *handle)
return !!hclgevf_read_dev(>hw, HCLGEVF_RST_ING);
 }
 
+static bool hclgevf_get_cmdq_stat(struct hnae3_handle *handle)
+{
+   struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+
+   return test_bit(HCLGEVF_STATE_CMD_DISABLE, >state);
+}
+
 static bool hclgevf_ae_dev_resetting(struct hnae3_handle *handle)
 {
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
@@ -3604,6 +3653,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.get_link_mode = hclgevf_get_link_mode,
.set_promisc_mode = hclgevf_set_promisc_mode,
.request_update_promisc_mode = hclgevf_request_update_promisc_mode,
+   .get_cmdq_stat = hclgevf_get_cmdq_stat,
 };
 
 static struct hnae3_ae_algo ae_algovf = {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
index c1fac89..c5bcc38 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
@@ -139,6 +139,7 @@ enum hclgevf_states {
HCLGEVF_STATE_IRQ_INITED,
HCLGEVF_STATE_REMOVING,
HCLGEVF_STATE_NIC_REGISTERED,
+

[PATCH net-next 6/7] net: hns3: debugfs add new command to query device specifications

2020-09-29 Thread Huazhong Tan
From: Guangbin Huang 

In order to query specifications of the device, add a new debugfs
command "dev spec" to do that.

Signed-off-by: Guangbin Huang 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 28 ++
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
index 15333ec..d6f8817 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -245,6 +245,7 @@ static void hns3_dbg_help(struct hnae3_handle *h)
dev_info(>pdev->dev, "queue map\n");
dev_info(>pdev->dev, "bd info  \n");
dev_info(>pdev->dev, "dev capability\n");
+   dev_info(>pdev->dev, "dev spec\n");
 
if (!hns3_is_phys_func(h->pdev))
return;
@@ -307,6 +308,31 @@ static void hns3_dbg_dev_caps(struct hnae3_handle *h)
 test_bit(HNAE3_DEV_SUPPORT_INT_QL_B, caps) ? "yes" : "no");
 }
 
+static void hns3_dbg_dev_specs(struct hnae3_handle *h)
+{
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
+   struct hnae3_dev_specs *dev_specs = _dev->dev_specs;
+   struct hnae3_knic_private_info *kinfo = >kinfo;
+   struct hns3_nic_priv *priv  = h->priv;
+
+   dev_info(priv->dev, "MAC entry num: %u\n", dev_specs->mac_entry_num);
+   dev_info(priv->dev, "MNG entry num: %u\n", dev_specs->mng_entry_num);
+   dev_info(priv->dev, "MAX non tso bd num: %u\n",
+dev_specs->max_non_tso_bd_num);
+   dev_info(priv->dev, "RSS ind tbl size: %u\n",
+dev_specs->rss_ind_tbl_size);
+   dev_info(priv->dev, "RSS key size: %u\n", dev_specs->rss_key_size);
+   dev_info(priv->dev, "RSS size: %u\n", kinfo->rss_size);
+   dev_info(priv->dev, "Allocated RSS size: %u\n", kinfo->req_rss_size);
+   dev_info(priv->dev, "Task queue pairs numbers: %u\n", kinfo->num_tqps);
+
+   dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len);
+   dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc);
+   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);
+}
+
 static ssize_t hns3_dbg_cmd_read(struct file *filp, char __user *buffer,
 size_t count, loff_t *ppos)
 {
@@ -384,6 +410,8 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const 
char __user *buffer,
ret = hns3_dbg_bd_info(handle, cmd_buf);
else if (strncmp(cmd_buf, "dev capability", 14) == 0)
hns3_dbg_dev_caps(handle);
+   else if (strncmp(cmd_buf, "dev spec", 8) == 0)
+   hns3_dbg_dev_specs(handle);
else if (handle->ae_algo->ops->dbg_run_cmd)
ret = handle->ae_algo->ops->dbg_run_cmd(handle, cmd_buf);
else
-- 
2.7.4



[PATCH net-next 3/7] net: hns3: add UDP segmentation offload support

2020-09-29 Thread Huazhong Tan
Add support for UDP segmentation offload to the HNS3 driver
when the device can do it.

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index df52abb..a362516 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -696,12 +696,19 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen,
 
/* normal or tunnel packet */
l4_offset = l4.hdr - skb->data;
-   hdr_len = (l4.tcp->doff << 2) + l4_offset;
 
/* remove payload length from inner pseudo checksum when tso */
l4_paylen = skb->len - l4_offset;
-   csum_replace_by_diff(>check,
-(__force __wsum)htonl(l4_paylen));
+
+   if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
+   hdr_len = sizeof(*l4.udp) + l4_offset;
+   csum_replace_by_diff(>check,
+(__force __wsum)htonl(l4_paylen));
+   } else {
+   hdr_len = (l4.tcp->doff << 2) + l4_offset;
+   csum_replace_by_diff(>check,
+(__force __wsum)htonl(l4_paylen));
+   }
 
/* find the txbd field values */
*paylen = skb->len - hdr_len;
@@ -2311,6 +2318,13 @@ static void hns3_set_default_feature(struct net_device 
*netdev)
netdev->features |= NETIF_F_NTUPLE;
}
}
+
+   if (test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, ae_dev->caps)) {
+   netdev->hw_features |= NETIF_F_GSO_UDP_L4;
+   netdev->features |= NETIF_F_GSO_UDP_L4;
+   netdev->vlan_features |= NETIF_F_GSO_UDP_L4;
+   netdev->hw_enc_features |= NETIF_F_GSO_UDP_L4;
+   }
 }
 
 static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
-- 
2.7.4



[PATCH net-next 2/7] net: hns3: rename trace event hns3_over_8bd

2020-09-29 Thread Huazhong Tan
Since the maximun BD number may not be 8 now, so rename
hns3_over_8bd() to hns3_over_max_bd().

Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c  | 4 ++--
 drivers/net/ethernet/hisilicon/hns3/hns3_trace.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a393755..df52abb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1283,7 +1283,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring 
*ring,
if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) &&
!hns3_skb_need_linearized(skb, bd_size, bd_num,
  max_non_tso_bd_num)) {
-   trace_hns3_over_8bd(skb);
+   trace_hns3_over_max_bd(skb);
goto out;
}
 
@@ -1294,7 +1294,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring 
*ring,
if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
(!skb_is_gso(skb) &&
 bd_num > max_non_tso_bd_num)) {
-   trace_hns3_over_8bd(skb);
+   trace_hns3_over_max_bd(skb);
return -ENOMEM;
}
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h
index 7bddcca..5153e5d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h
@@ -53,7 +53,7 @@ DECLARE_EVENT_CLASS(hns3_skb_template,
)
 );
 
-DEFINE_EVENT(hns3_skb_template, hns3_over_8bd,
+DEFINE_EVENT(hns3_skb_template, hns3_over_max_bd,
TP_PROTO(struct sk_buff *skb),
TP_ARGS(skb));
 
-- 
2.7.4



[PATCH net-next 00/10] net: hns3: updates for -next

2020-09-27 Thread Huazhong Tan
To facilitate code maintenance and compatibility, #1 and #2 add
device version to replace pci revision, #3 to #9 adds support for
querying device capabilities and specifications, then the driver
can use these query results to implement corresponding features
(some features will be implemented later).

And #10 is a minor cleanup since too many parameters for
hclge_shaper_para_calc().

Guangbin Huang (9):
  net: hns3: add device version to replace pci revision
  net: hns3: delete redundant PCI revision judgement
  net: hns3: add support to query device capability
  net: hns3: use capability flag to indicate FEC
  net: hns3: use capabilities queried from firmware
  net: hns3: add debugfs to dump device capabilities
  net: hns3: add support to query device specifications
  net: hns3: replace the macro of max tm rate with the queried
specification
  net: hns3: add a check for device specifications queried from firmware

Huazhong Tan (1):
  net: hns3: add a structure for IR shaper's parameter in
hclge_shaper_para_calc()

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  81 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c |  24 +
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c|  20 ++--
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  30 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |  65 +---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  36 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c |  14 +--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 117 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 101 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |   8 ++
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c   |  62 ---
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h   |  34 +-
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |  94 +++--
 13 files changed, 548 insertions(+), 138 deletions(-)

-- 
2.7.4



[PATCH net-next 04/10] net: hns3: use capability flag to indicate FEC

2020-09-27 Thread Huazhong Tan
From: Guangbin Huang 

Currently, the revision of the pci device is used to identify
whether FEC is supported, which is not good for maintainability
and compatibility. So use a capability flag to do that.

Signed-off-by: Guangbin Huang 
Signed-off-by: Huazhong Tan 
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h | 4 
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c  | 6 --
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c  | 1 +
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 ++--
 4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index e5835ee..7a6a17d 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -63,6 +63,7 @@
 #define HNAE3_ROCE_CLIENT_INITED_B 0x5
 #define HNAE3_DEV_SUPPORT_FD_B 0x6
 #define HNAE3_DEV_SUPPORT_GRO_B0x7
+#define HNAE3_DEV_SUPPORT_FEC_B0x9
 
 #define HNAE3_DEV_SUPPORT_ROCE_DCB_BITS (BIT(HNAE3_DEV_SUPPORT_DCB_B) |\
BIT(HNAE3_DEV_SUPPORT_ROCE_B))
@@ -79,6 +80,9 @@
 #define hnae3_dev_gro_supported(hdev) \
hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_GRO_B)
 
+#define hnae3_dev_fec_supported(hdev) \
+   hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_FEC_B)
+
 #define ring_ptr_move_fw(ring, p) \
((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
 #define ring_ptr_move_bw(ring, p) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 96b4d97..c57ec5e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1363,11 +1363,12 @@ static int hns3_get_fecparam(struct net_device *netdev,
 struct ethtool_fecparam *fec)
 {
struct hnae3_handle *handle = hns3_get_handle(netdev);
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
u8 fec_ability;
u8 fec_mode;
 
-   if (handle->pdev->revision == 0x20)
+   if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_FEC_B))
return -EOPNOTSUPP;
 
if (!ops->get_fec)
@@ -1385,10 +1386,11 @@ static int hns3_set_fecparam(struct net_device *netdev,
 struct ethtool_fecparam *fec)
 {
struct hnae3_handle *handle = hns3_get_handle(netdev);
+   struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
u32 fec_mode;
 
-   if (handle->pdev->revision == 0x20)
+   if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_FEC_B))
return -EOPNOTSUPP;
 
if (!ops->set_fec)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 9f6b1a6..127f693 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -355,6 +355,7 @@ hclge_cmd_query_version_and_capability(struct hclge_dev 
*hdev)
ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
hnae3_set_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_FD_B, 1);
hnae3_set_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_GRO_B, 1);
+   hnae3_set_bit(ae_dev->flag, HNAE3_DEV_SUPPORT_FEC_B, 1);
}
 
return ret;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index cc6d347..871632a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1157,7 +1157,7 @@ static void hclge_parse_fiber_link_mode(struct hclge_dev 
*hdev,
hclge_convert_setting_sr(mac, speed_ability);
hclge_convert_setting_lr(mac, speed_ability);
hclge_convert_setting_cr(mac, speed_ability);
-   if (hdev->pdev->revision >= 0x21)
+   if (hnae3_dev_fec_supported(hdev))
hclge_convert_setting_fec(mac);
 
linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, mac->supported);
@@ -1171,7 +1171,7 @@ static void hclge_parse_backplane_link_mode(struct 
hclge_dev *hdev,
struct hclge_mac *mac = >hw.mac;
 
hclge_convert_setting_kr(mac, speed_ability);
-   if (hdev->pdev->revision >= 0x21)
+   if (hnae3_dev_fec_supported(hdev))
hclge_convert_setting_fec(mac);
linkmode_set_bit(ETHTOOL_LINK_MODE_Backplane_BIT, mac->supported);
linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, mac->supported);
-- 
2.7.4



  1   2   3   4   5   6   7   >