Commit f52ea3c5 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-next'

Huazhong Tan says:

====================
net: hns3: add some bugfixes & optimizations & cleanups for HNS3 driver

This patch-set includes code optimizations, bugfixes and cleanups for
the HNS3 ethernet controller driver.

[patch 01/12] fixes a GFP flag error.

[patch 02/12] fixes a VF interrupt error.

[patch 03/12] adds a cleanup for VLAN handling.

[patch 04/12] fixes a bug in debugfs.

[patch 05/12] modifies pause displaying format.

[patch 06/12] adds more DFX information for ethtool -d.

[patch 07/12] adds more TX statistics information.

[patch 08/12] adds a check for TX BD number.

[patch 09/12] adds a cleanup for dumping NCL_CONFIG.

[patch 10/12] refines function for querying MAC pause statistics.

[patch 11/12] adds a handshake with VF when doing PF reset.

[patch 12/12] refines some macro definitions.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ca497fb6 eddd9860
...@@ -58,10 +58,10 @@ ...@@ -58,10 +58,10 @@
BIT(HNAE3_DEV_SUPPORT_ROCE_B)) BIT(HNAE3_DEV_SUPPORT_ROCE_B))
#define hnae3_dev_roce_supported(hdev) \ #define hnae3_dev_roce_supported(hdev) \
hnae3_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B) hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)
#define hnae3_dev_dcb_supported(hdev) \ #define hnae3_dev_dcb_supported(hdev) \
hnae3_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_DCB_B) hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_DCB_B)
#define hnae3_dev_fd_supported(hdev) \ #define hnae3_dev_fd_supported(hdev) \
hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_FD_B) hnae3_get_bit((hdev)->ae_dev->flag, HNAE3_DEV_SUPPORT_FD_B)
...@@ -91,6 +91,11 @@ struct hnae3_queue { ...@@ -91,6 +91,11 @@ struct hnae3_queue {
u16 rx_desc_num;/* total number of rx desc */ u16 rx_desc_num;/* total number of rx desc */
}; };
struct hns3_mac_stats {
u64 tx_pause_cnt;
u64 rx_pause_cnt;
};
/*hnae3 loop mode*/ /*hnae3 loop mode*/
enum hnae3_loop { enum hnae3_loop {
HNAE3_LOOP_APP, HNAE3_LOOP_APP,
...@@ -298,6 +303,8 @@ struct hnae3_ae_dev { ...@@ -298,6 +303,8 @@ struct hnae3_ae_dev {
* Remove multicast address from mac table * Remove multicast address from mac table
* update_stats() * update_stats()
* Update Old network device statistics * Update Old network device statistics
* get_mac_stats()
* get mac pause statistics including tx_cnt and rx_cnt
* get_ethtool_stats() * get_ethtool_stats()
* Get ethtool network device statistics * Get ethtool network device statistics
* get_strings() * get_strings()
...@@ -426,8 +433,8 @@ struct hnae3_ae_ops { ...@@ -426,8 +433,8 @@ struct hnae3_ae_ops {
void (*update_stats)(struct hnae3_handle *handle, void (*update_stats)(struct hnae3_handle *handle,
struct net_device_stats *net_stats); struct net_device_stats *net_stats);
void (*get_stats)(struct hnae3_handle *handle, u64 *data); void (*get_stats)(struct hnae3_handle *handle, u64 *data);
void (*get_mac_pause_stats)(struct hnae3_handle *handle, u64 *tx_cnt, void (*get_mac_stats)(struct hnae3_handle *handle,
u64 *rx_cnt); struct hns3_mac_stats *mac_stats);
void (*get_strings)(struct hnae3_handle *handle, void (*get_strings)(struct hnae3_handle *handle,
u32 stringset, u8 *data); u32 stringset, u8 *data);
int (*get_sset_count)(struct hnae3_handle *handle, int stringset); int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "hns3_enet.h" #include "hns3_enet.h"
#define HNS3_DBG_READ_LEN 256 #define HNS3_DBG_READ_LEN 256
#define HNS3_DBG_WRITE_LEN 1024
static struct dentry *hns3_dbgfs_root; static struct dentry *hns3_dbgfs_root;
...@@ -322,6 +323,9 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer, ...@@ -322,6 +323,9 @@ static ssize_t hns3_dbg_cmd_write(struct file *filp, const char __user *buffer,
test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
return 0; return 0;
if (count > HNS3_DBG_WRITE_LEN)
return -ENOSPC;
cmd_buf = kzalloc(count + 1, GFP_KERNEL); cmd_buf = kzalloc(count + 1, GFP_KERNEL);
if (!cmd_buf) if (!cmd_buf)
return count; return count;
......
...@@ -195,7 +195,8 @@ enum hns3_nic_state { ...@@ -195,7 +195,8 @@ enum hns3_nic_state {
#define HNS3_VECTOR_INITED 1 #define HNS3_VECTOR_INITED 1
#define HNS3_MAX_BD_SIZE 65535 #define HNS3_MAX_BD_SIZE 65535
#define HNS3_MAX_BD_PER_FRAG 8 #define HNS3_MAX_BD_NUM_NORMAL 8
#define HNS3_MAX_BD_NUM_TSO 63
#define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS #define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS
#define HNS3_VECTOR_GL0_OFFSET 0x100 #define HNS3_VECTOR_GL0_OFFSET 0x100
...@@ -377,6 +378,10 @@ struct ring_stats { ...@@ -377,6 +378,10 @@ struct ring_stats {
u64 restart_queue; u64 restart_queue;
u64 tx_busy; u64 tx_busy;
u64 tx_copy; u64 tx_copy;
u64 tx_vlan_err;
u64 tx_l4_proto_err;
u64 tx_l2l3l4_err;
u64 tx_tso_err;
}; };
struct { struct {
u64 rx_pkts; u64 rx_pkts;
......
...@@ -30,6 +30,10 @@ static const struct hns3_stats hns3_txq_stats[] = { ...@@ -30,6 +30,10 @@ static const struct hns3_stats hns3_txq_stats[] = {
HNS3_TQP_STAT("wake", restart_queue), HNS3_TQP_STAT("wake", restart_queue),
HNS3_TQP_STAT("busy", tx_busy), HNS3_TQP_STAT("busy", tx_busy),
HNS3_TQP_STAT("copy", tx_copy), HNS3_TQP_STAT("copy", tx_copy),
HNS3_TQP_STAT("vlan_err", tx_vlan_err),
HNS3_TQP_STAT("l4_proto_err", tx_l4_proto_err),
HNS3_TQP_STAT("l2l3l4_err", tx_l2l3l4_err),
HNS3_TQP_STAT("tso_err", tx_tso_err),
}; };
#define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats) #define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats)
......
...@@ -87,6 +87,7 @@ enum hclge_opcode_type { ...@@ -87,6 +87,7 @@ enum hclge_opcode_type {
HCLGE_OPC_QUERY_VF_RSRC = 0x0024, HCLGE_OPC_QUERY_VF_RSRC = 0x0024,
HCLGE_OPC_GET_CFG_PARAM = 0x0025, HCLGE_OPC_GET_CFG_PARAM = 0x0025,
HCLGE_OPC_PF_RST_DONE = 0x0026, HCLGE_OPC_PF_RST_DONE = 0x0026,
HCLGE_OPC_QUERY_VF_RST_RDY = 0x0027,
HCLGE_OPC_STATS_64_BIT = 0x0030, HCLGE_OPC_STATS_64_BIT = 0x0030,
HCLGE_OPC_STATS_32_BIT = 0x0031, HCLGE_OPC_STATS_32_BIT = 0x0031,
...@@ -588,6 +589,12 @@ struct hclge_config_mac_mode_cmd { ...@@ -588,6 +589,12 @@ struct hclge_config_mac_mode_cmd {
u8 rsv[20]; u8 rsv[20];
}; };
struct hclge_pf_rst_sync_cmd {
#define HCLGE_PF_RST_ALL_VF_RDY_B 0
u8 all_vf_ready;
u8 rsv[23];
};
#define HCLGE_CFG_SPEED_S 0 #define HCLGE_CFG_SPEED_S 0
#define HCLGE_CFG_SPEED_M GENMASK(5, 0) #define HCLGE_CFG_SPEED_M GENMASK(5, 0)
......
...@@ -14,16 +14,8 @@ static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset) ...@@ -14,16 +14,8 @@ static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset)
struct hclge_desc desc[4]; struct hclge_desc desc[4];
int ret; int ret;
hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_DFX_BD_NUM, true); ret = hclge_query_bd_num_cmd_send(hdev, desc);
desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); if (ret) {
hclge_cmd_setup_basic_desc(&desc[1], HCLGE_OPC_DFX_BD_NUM, true);
desc[1].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
hclge_cmd_setup_basic_desc(&desc[2], HCLGE_OPC_DFX_BD_NUM, true);
desc[2].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
hclge_cmd_setup_basic_desc(&desc[3], HCLGE_OPC_DFX_BD_NUM, true);
ret = hclge_cmd_send(&hdev->hw, desc, 4);
if (ret != HCLGE_CMD_EXEC_SUCCESS) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"get dfx bdnum fail, status is %d.\n", ret); "get dfx bdnum fail, status is %d.\n", ret);
return ret; return ret;
...@@ -1003,6 +995,33 @@ void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev) ...@@ -1003,6 +995,33 @@ void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev)
kfree(desc_src); kfree(desc_src);
} }
#define HCLGE_CMD_NCL_CONFIG_BD_NUM 5
static void hclge_ncl_config_data_print(struct hclge_dev *hdev,
struct hclge_desc *desc, int *offset,
int *length)
{
#define HCLGE_CMD_DATA_NUM 6
int i;
int j;
for (i = 0; i < HCLGE_CMD_NCL_CONFIG_BD_NUM; i++) {
for (j = 0; j < HCLGE_CMD_DATA_NUM; j++) {
if (i == 0 && j == 0)
continue;
dev_info(&hdev->pdev->dev, "0x%04x | 0x%08x\n",
*offset,
le32_to_cpu(desc[i].data[j]));
*offset += sizeof(u32);
*length -= sizeof(u32);
if (*length <= 0)
return;
}
}
}
/* hclge_dbg_dump_ncl_config: print specified range of NCL_CONFIG file /* hclge_dbg_dump_ncl_config: print specified range of NCL_CONFIG file
* @hdev: pointer to struct hclge_dev * @hdev: pointer to struct hclge_dev
* @cmd_buf: string that contains offset and length * @cmd_buf: string that contains offset and length
...@@ -1012,17 +1031,13 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev, ...@@ -1012,17 +1031,13 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev,
{ {
#define HCLGE_MAX_NCL_CONFIG_OFFSET 4096 #define HCLGE_MAX_NCL_CONFIG_OFFSET 4096
#define HCLGE_MAX_NCL_CONFIG_LENGTH (20 + 24 * 4) #define HCLGE_MAX_NCL_CONFIG_LENGTH (20 + 24 * 4)
#define HCLGE_CMD_DATA_NUM 6
struct hclge_desc desc[5]; struct hclge_desc desc[HCLGE_CMD_NCL_CONFIG_BD_NUM];
u32 byte_offset; int bd_num = HCLGE_CMD_NCL_CONFIG_BD_NUM;
int bd_num = 5;
int offset; int offset;
int length; int length;
int data0; int data0;
int ret; int ret;
int i;
int j;
ret = sscanf(cmd_buf, "%x %x", &offset, &length); ret = sscanf(cmd_buf, "%x %x", &offset, &length);
if (ret != 2 || offset >= HCLGE_MAX_NCL_CONFIG_OFFSET || if (ret != 2 || offset >= HCLGE_MAX_NCL_CONFIG_OFFSET ||
...@@ -1048,22 +1063,7 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev, ...@@ -1048,22 +1063,7 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev,
if (ret) if (ret)
return; return;
byte_offset = offset; hclge_ncl_config_data_print(hdev, desc, &offset, &length);
for (i = 0; i < bd_num; i++) {
for (j = 0; j < HCLGE_CMD_DATA_NUM; j++) {
if (i == 0 && j == 0)
continue;
dev_info(&hdev->pdev->dev, "0x%04x | 0x%08x\n",
byte_offset,
le32_to_cpu(desc[i].data[j]));
byte_offset += sizeof(u32);
length -= sizeof(u32);
if (length <= 0)
return;
}
}
offset += HCLGE_MAX_NCL_CONFIG_LENGTH;
} }
} }
......
...@@ -1029,4 +1029,6 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, ...@@ -1029,4 +1029,6 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
u16 state, u16 vlan_tag, u16 qos, u16 state, u16 vlan_tag, u16 qos,
u16 vlan_proto); u16 vlan_proto);
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time); void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
struct hclge_desc *desc);
#endif #endif
...@@ -1889,21 +1889,20 @@ static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr) ...@@ -1889,21 +1889,20 @@ static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr)
static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
u32 *clearval) u32 *clearval)
{ {
u32 val, cmdq_src_reg, rst_ing_reg; u32 val, cmdq_stat_reg, rst_ing_reg;
/* fetch the events from their corresponding regs */ /* fetch the events from their corresponding regs */
cmdq_src_reg = hclgevf_read_dev(&hdev->hw, cmdq_stat_reg = hclgevf_read_dev(&hdev->hw,
HCLGEVF_VECTOR0_CMDQ_SRC_REG); HCLGEVF_VECTOR0_CMDQ_STAT_REG);
if (BIT(HCLGEVF_VECTOR0_RST_INT_B) & cmdq_src_reg) { if (BIT(HCLGEVF_VECTOR0_RST_INT_B) & cmdq_stat_reg) {
rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
dev_info(&hdev->pdev->dev, dev_info(&hdev->pdev->dev,
"receive reset interrupt 0x%x!\n", rst_ing_reg); "receive reset interrupt 0x%x!\n", rst_ing_reg);
set_bit(HNAE3_VF_RESET, &hdev->reset_pending); set_bit(HNAE3_VF_RESET, &hdev->reset_pending);
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
cmdq_src_reg &= ~BIT(HCLGEVF_VECTOR0_RST_INT_B); *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B);
*clearval = cmdq_src_reg;
hdev->rst_stats.vf_rst_cnt++; hdev->rst_stats.vf_rst_cnt++;
/* set up VF hardware reset status, its PF will clear /* set up VF hardware reset status, its PF will clear
* this status when PF has initialized done. * this status when PF has initialized done.
...@@ -1915,9 +1914,20 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, ...@@ -1915,9 +1914,20 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
} }
/* check for vector0 mailbox(=CMDQ RX) event source */ /* check for vector0 mailbox(=CMDQ RX) event source */
if (BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) { if (BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B) & cmdq_stat_reg) {
cmdq_src_reg &= ~BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B); /* for revision 0x21, clearing interrupt is writing bit 0
*clearval = cmdq_src_reg; * to the clear register, writing bit 1 means to keep the
* old value.
* for revision 0x20, the clear register is a read & write
* register, so we should just write 0 to the bit we are
* handling, and keep other bits as cmdq_stat_reg.
*/
if (hdev->pdev->revision >= 0x21)
*clearval = ~(1U << HCLGEVF_VECTOR0_RX_CMDQ_INT_B);
else
*clearval = cmdq_stat_reg &
~BIT(HCLGEVF_VECTOR0_RX_CMDQ_INT_B);
return HCLGEVF_VECTOR0_EVENT_MBX; return HCLGEVF_VECTOR0_EVENT_MBX;
} }
......
...@@ -87,6 +87,8 @@ ...@@ -87,6 +87,8 @@
/* Vector0 interrupt CMDQ event source register(RW) */ /* Vector0 interrupt CMDQ event source register(RW) */
#define HCLGEVF_VECTOR0_CMDQ_SRC_REG 0x27100 #define HCLGEVF_VECTOR0_CMDQ_SRC_REG 0x27100
/* Vector0 interrupt CMDQ event status register(RO) */
#define HCLGEVF_VECTOR0_CMDQ_STAT_REG 0x27104
/* CMDQ register bits for RX event(=MBX event) */ /* CMDQ register bits for RX event(=MBX event) */
#define HCLGEVF_VECTOR0_RX_CMDQ_INT_B 1 #define HCLGEVF_VECTOR0_RX_CMDQ_INT_B 1
/* RST register bits for RESET event */ /* RST register bits for RESET event */
...@@ -123,7 +125,7 @@ ...@@ -123,7 +125,7 @@
#define HCLGEVF_S_IP_BIT BIT(3) #define HCLGEVF_S_IP_BIT BIT(3)
#define HCLGEVF_V_TAG_BIT BIT(4) #define HCLGEVF_V_TAG_BIT BIT(4)
#define HCLGEVF_STATS_TIMER_INTERVAL (36) #define HCLGEVF_STATS_TIMER_INTERVAL 36U
enum hclgevf_evt_cause { enum hclgevf_evt_cause {
HCLGEVF_VECTOR0_EVENT_RST, HCLGEVF_VECTOR0_EVENT_RST,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment