aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-01-22 16:05:50 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-22 16:05:50 -0500
commit3dff4c621f687fe34d6cef2a331cd386a562376e (patch)
tree2d0f0bcfde73b983527d1f4edfeac8217b78bd0f
parentb2d3bcfa26a7a8de41f358a6cae8b848673b3c6e (diff)
parent716aaac1f3f3ee141f550d2d6d7934eab42c1c29 (diff)
Merge branch 'hns3-new-features'
Peng Li says: ==================== add some features to hns3 driver This patchset adds some features to hns3 driver, include the support for ethtool command -d, -p and support for manager table. [Patch 1/4] adds support for ethtool command -d, its ops is get_regs. driver will send command to command queue, and get regs number and regs value from command queue. [Patch 2/4] adds manager table initialization for hardware. [Patch 3/4] adds support for ethtool command -p. For fiber ports, driver sends command to command queue, and IMP will write SGPIO regs to control leds. [Patch 4/4] adds support for net status led for fiber ports. Net status include port speed, total rx/tx packets and link status. Driver send the status to command queue, and IMP will write SGPIO to control leds. --- Change log: V1 -> V2: 1, fix comments from Andrew Lunn, remove the patch "net: hns3: add ethtool -p support for phy device". ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h5
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c35
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h47
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c456
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h3
5 files changed, 545 insertions, 1 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 634e9327968b..fd06bc78c58e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -356,7 +356,8 @@ struct hnae3_ae_ops {
356 u32 stringset, u8 *data); 356 u32 stringset, u8 *data);
357 int (*get_sset_count)(struct hnae3_handle *handle, int stringset); 357 int (*get_sset_count)(struct hnae3_handle *handle, int stringset);
358 358
359 void (*get_regs)(struct hnae3_handle *handle, void *data); 359 void (*get_regs)(struct hnae3_handle *handle, u32 *version,
360 void *data);
360 int (*get_regs_len)(struct hnae3_handle *handle); 361 int (*get_regs_len)(struct hnae3_handle *handle);
361 362
362 u32 (*get_rss_key_size)(struct hnae3_handle *handle); 363 u32 (*get_rss_key_size)(struct hnae3_handle *handle);
@@ -404,6 +405,8 @@ struct hnae3_ae_ops {
404 int (*set_channels)(struct hnae3_handle *handle, u32 new_tqps_num); 405 int (*set_channels)(struct hnae3_handle *handle, u32 new_tqps_num);
405 void (*get_flowctrl_adv)(struct hnae3_handle *handle, 406 void (*get_flowctrl_adv)(struct hnae3_handle *handle,
406 u32 *flowctrl_adv); 407 u32 *flowctrl_adv);
408 int (*set_led_id)(struct hnae3_handle *handle,
409 enum ethtool_phys_id_state status);
407}; 410};
408 411
409struct hnae3_dcb_ops { 412struct hnae3_dcb_ops {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 358f78036941..741020534b16 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -1063,6 +1063,38 @@ static int hns3_set_coalesce(struct net_device *netdev,
1063 return 0; 1063 return 0;
1064} 1064}
1065 1065
1066static int hns3_get_regs_len(struct net_device *netdev)
1067{
1068 struct hnae3_handle *h = hns3_get_handle(netdev);
1069
1070 if (!h->ae_algo->ops->get_regs_len)
1071 return -EOPNOTSUPP;
1072
1073 return h->ae_algo->ops->get_regs_len(h);
1074}
1075
1076static void hns3_get_regs(struct net_device *netdev,
1077 struct ethtool_regs *cmd, void *data)
1078{
1079 struct hnae3_handle *h = hns3_get_handle(netdev);
1080
1081 if (!h->ae_algo->ops->get_regs)
1082 return;
1083
1084 h->ae_algo->ops->get_regs(h, &cmd->version, data);
1085}
1086
1087static int hns3_set_phys_id(struct net_device *netdev,
1088 enum ethtool_phys_id_state state)
1089{
1090 struct hnae3_handle *h = hns3_get_handle(netdev);
1091
1092 if (!h->ae_algo || !h->ae_algo->ops || !h->ae_algo->ops->set_led_id)
1093 return -EOPNOTSUPP;
1094
1095 return h->ae_algo->ops->set_led_id(h, state);
1096}
1097
1066static const struct ethtool_ops hns3vf_ethtool_ops = { 1098static const struct ethtool_ops hns3vf_ethtool_ops = {
1067 .get_drvinfo = hns3_get_drvinfo, 1099 .get_drvinfo = hns3_get_drvinfo,
1068 .get_ringparam = hns3_get_ringparam, 1100 .get_ringparam = hns3_get_ringparam,
@@ -1103,6 +1135,9 @@ static const struct ethtool_ops hns3_ethtool_ops = {
1103 .set_channels = hns3_set_channels, 1135 .set_channels = hns3_set_channels,
1104 .get_coalesce = hns3_get_coalesce, 1136 .get_coalesce = hns3_get_coalesce,
1105 .set_coalesce = hns3_set_coalesce, 1137 .set_coalesce = hns3_set_coalesce,
1138 .get_regs_len = hns3_get_regs_len,
1139 .get_regs = hns3_get_regs,
1140 .set_phys_id = hns3_set_phys_id,
1106}; 1141};
1107 1142
1108void hns3_ethtool_set_ops(struct net_device *netdev) 1143void hns3_ethtool_set_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 3c3159b2d3bf..3fd10a6bec53 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -102,6 +102,10 @@ enum hclge_opcode_type {
102 HCLGE_OPC_STATS_64_BIT = 0x0030, 102 HCLGE_OPC_STATS_64_BIT = 0x0030,
103 HCLGE_OPC_STATS_32_BIT = 0x0031, 103 HCLGE_OPC_STATS_32_BIT = 0x0031,
104 HCLGE_OPC_STATS_MAC = 0x0032, 104 HCLGE_OPC_STATS_MAC = 0x0032,
105
106 HCLGE_OPC_QUERY_REG_NUM = 0x0040,
107 HCLGE_OPC_QUERY_32_BIT_REG = 0x0041,
108 HCLGE_OPC_QUERY_64_BIT_REG = 0x0042,
105 /* Device management command */ 109 /* Device management command */
106 110
107 /* MAC commond */ 111 /* MAC commond */
@@ -111,6 +115,7 @@ enum hclge_opcode_type {
111 HCLGE_OPC_QUERY_LINK_STATUS = 0x0307, 115 HCLGE_OPC_QUERY_LINK_STATUS = 0x0307,
112 HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, 116 HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308,
113 HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309, 117 HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309,
118 HCLGE_OPC_STATS_MAC_TRAFFIC = 0x0314,
114 /* MACSEC command */ 119 /* MACSEC command */
115 120
116 /* PFC/Pause CMD*/ 121 /* PFC/Pause CMD*/
@@ -223,6 +228,9 @@ enum hclge_opcode_type {
223 228
224 /* Mailbox cmd */ 229 /* Mailbox cmd */
225 HCLGEVF_OPC_MBX_PF_TO_VF = 0x2000, 230 HCLGEVF_OPC_MBX_PF_TO_VF = 0x2000,
231
232 /* Led command */
233 HCLGE_OPC_LED_STATUS_CFG = 0xB000,
226}; 234};
227 235
228#define HCLGE_TQP_REG_OFFSET 0x80000 236#define HCLGE_TQP_REG_OFFSET 0x80000
@@ -601,6 +609,28 @@ struct hclge_mac_vlan_mask_entry_cmd {
601 u8 rsv2[14]; 609 u8 rsv2[14];
602}; 610};
603 611
612#define HCLGE_MAC_MGR_MASK_VLAN_B BIT(0)
613#define HCLGE_MAC_MGR_MASK_MAC_B BIT(1)
614#define HCLGE_MAC_MGR_MASK_ETHERTYPE_B BIT(2)
615#define HCLGE_MAC_ETHERTYPE_LLDP 0x88cc
616
617struct hclge_mac_mgr_tbl_entry_cmd {
618 u8 flags;
619 u8 resp_code;
620 __le16 vlan_tag;
621 __le32 mac_addr_hi32;
622 __le16 mac_addr_lo16;
623 __le16 rsv1;
624 __le16 ethter_type;
625 __le16 egress_port;
626 __le16 egress_queue;
627 u8 sw_port_id_aware;
628 u8 rsv2;
629 u8 i_port_bitmap;
630 u8 i_port_direction;
631 u8 rsv3[2];
632};
633
604#define HCLGE_CFG_MTA_MAC_SEL_S 0x0 634#define HCLGE_CFG_MTA_MAC_SEL_S 0x0
605#define HCLGE_CFG_MTA_MAC_SEL_M GENMASK(1, 0) 635#define HCLGE_CFG_MTA_MAC_SEL_M GENMASK(1, 0)
606#define HCLGE_CFG_MTA_MAC_EN_B 0x7 636#define HCLGE_CFG_MTA_MAC_EN_B 0x7
@@ -781,6 +811,23 @@ struct hclge_reset_cmd {
781#define HCLGE_NIC_CMQ_DESC_NUM 1024 811#define HCLGE_NIC_CMQ_DESC_NUM 1024
782#define HCLGE_NIC_CMQ_DESC_NUM_S 3 812#define HCLGE_NIC_CMQ_DESC_NUM_S 3
783 813
814#define HCLGE_LED_PORT_SPEED_STATE_S 0
815#define HCLGE_LED_PORT_SPEED_STATE_M GENMASK(5, 0)
816#define HCLGE_LED_ACTIVITY_STATE_S 0
817#define HCLGE_LED_ACTIVITY_STATE_M GENMASK(1, 0)
818#define HCLGE_LED_LINK_STATE_S 0
819#define HCLGE_LED_LINK_STATE_M GENMASK(1, 0)
820#define HCLGE_LED_LOCATE_STATE_S 0
821#define HCLGE_LED_LOCATE_STATE_M GENMASK(1, 0)
822
823struct hclge_set_led_state_cmd {
824 u8 port_speed_led_config;
825 u8 link_led_config;
826 u8 activity_led_config;
827 u8 locate_led_config;
828 u8 rsv[20];
829};
830
784int hclge_cmd_init(struct hclge_dev *hdev); 831int hclge_cmd_init(struct hclge_dev *hdev);
785static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value) 832static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value)
786{ 833{
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 27f0ab695f5a..32bc6f68e297 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -39,6 +39,7 @@ static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
39static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu); 39static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu);
40static int hclge_init_vlan_config(struct hclge_dev *hdev); 40static int hclge_init_vlan_config(struct hclge_dev *hdev);
41static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev); 41static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev);
42static int hclge_update_led_status(struct hclge_dev *hdev);
42 43
43static struct hnae3_ae_algo ae_algo; 44static struct hnae3_ae_algo ae_algo;
44 45
@@ -392,6 +393,16 @@ static const struct hclge_comm_stats_str g_mac_stats_string[] = {
392 HCLGE_MAC_STATS_FIELD_OFF(mac_rx_send_app_bad_pkt_num)} 393 HCLGE_MAC_STATS_FIELD_OFF(mac_rx_send_app_bad_pkt_num)}
393}; 394};
394 395
396static const struct hclge_mac_mgr_tbl_entry_cmd hclge_mgr_table[] = {
397 {
398 .flags = HCLGE_MAC_MGR_MASK_VLAN_B,
399 .ethter_type = cpu_to_le16(HCLGE_MAC_ETHERTYPE_LLDP),
400 .mac_addr_hi32 = cpu_to_le32(htonl(0x0180C200)),
401 .mac_addr_lo16 = cpu_to_le16(htons(0x000E)),
402 .i_port_bitmap = 0x1,
403 },
404};
405
395static int hclge_64_bit_update_stats(struct hclge_dev *hdev) 406static int hclge_64_bit_update_stats(struct hclge_dev *hdev)
396{ 407{
397#define HCLGE_64_BIT_CMD_NUM 5 408#define HCLGE_64_BIT_CMD_NUM 5
@@ -495,6 +506,38 @@ static int hclge_32_bit_update_stats(struct hclge_dev *hdev)
495 return 0; 506 return 0;
496} 507}
497 508
509static int hclge_mac_get_traffic_stats(struct hclge_dev *hdev)
510{
511 struct hclge_mac_stats *mac_stats = &hdev->hw_stats.mac_stats;
512 struct hclge_desc desc;
513 __le64 *desc_data;
514 int ret;
515
516 /* for fiber port, need to query the total rx/tx packets statstics,
517 * used for data transferring checking.
518 */
519 if (hdev->hw.mac.media_type != HNAE3_MEDIA_TYPE_FIBER)
520 return 0;
521
522 if (test_bit(HCLGE_STATE_STATISTICS_UPDATING, &hdev->state))
523 return 0;
524
525 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_STATS_MAC_TRAFFIC, true);
526 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
527 if (ret) {
528 dev_err(&hdev->pdev->dev,
529 "Get MAC total pkt stats fail, ret = %d\n", ret);
530
531 return ret;
532 }
533
534 desc_data = (__le64 *)(&desc.data[0]);
535 mac_stats->mac_tx_total_pkt_num += le64_to_cpu(*desc_data++);
536 mac_stats->mac_rx_total_pkt_num += le64_to_cpu(*desc_data);
537
538 return 0;
539}
540
498static int hclge_mac_update_stats(struct hclge_dev *hdev) 541static int hclge_mac_update_stats(struct hclge_dev *hdev)
499{ 542{
500#define HCLGE_MAC_CMD_NUM 21 543#define HCLGE_MAC_CMD_NUM 21
@@ -2836,13 +2879,20 @@ static void hclge_service_task(struct work_struct *work)
2836 struct hclge_dev *hdev = 2879 struct hclge_dev *hdev =
2837 container_of(work, struct hclge_dev, service_task); 2880 container_of(work, struct hclge_dev, service_task);
2838 2881
2882 /* The total rx/tx packets statstics are wanted to be updated
2883 * per second. Both hclge_update_stats_for_all() and
2884 * hclge_mac_get_traffic_stats() can do it.
2885 */
2839 if (hdev->hw_stats.stats_timer >= HCLGE_STATS_TIMER_INTERVAL) { 2886 if (hdev->hw_stats.stats_timer >= HCLGE_STATS_TIMER_INTERVAL) {
2840 hclge_update_stats_for_all(hdev); 2887 hclge_update_stats_for_all(hdev);
2841 hdev->hw_stats.stats_timer = 0; 2888 hdev->hw_stats.stats_timer = 0;
2889 } else {
2890 hclge_mac_get_traffic_stats(hdev);
2842 } 2891 }
2843 2892
2844 hclge_update_speed_duplex(hdev); 2893 hclge_update_speed_duplex(hdev);
2845 hclge_update_link_status(hdev); 2894 hclge_update_link_status(hdev);
2895 hclge_update_led_status(hdev);
2846 hclge_service_complete(hdev); 2896 hclge_service_complete(hdev);
2847} 2897}
2848 2898
@@ -4249,6 +4299,91 @@ int hclge_rm_mc_addr_common(struct hclge_vport *vport,
4249 return status; 4299 return status;
4250} 4300}
4251 4301
4302static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev,
4303 u16 cmdq_resp, u8 resp_code)
4304{
4305#define HCLGE_ETHERTYPE_SUCCESS_ADD 0
4306#define HCLGE_ETHERTYPE_ALREADY_ADD 1
4307#define HCLGE_ETHERTYPE_MGR_TBL_OVERFLOW 2
4308#define HCLGE_ETHERTYPE_KEY_CONFLICT 3
4309
4310 int return_status;
4311
4312 if (cmdq_resp) {
4313 dev_err(&hdev->pdev->dev,
4314 "cmdq execute failed for get_mac_ethertype_cmd_status, status=%d.\n",
4315 cmdq_resp);
4316 return -EIO;
4317 }
4318
4319 switch (resp_code) {
4320 case HCLGE_ETHERTYPE_SUCCESS_ADD:
4321 case HCLGE_ETHERTYPE_ALREADY_ADD:
4322 return_status = 0;
4323 break;
4324 case HCLGE_ETHERTYPE_MGR_TBL_OVERFLOW:
4325 dev_err(&hdev->pdev->dev,
4326 "add mac ethertype failed for manager table overflow.\n");
4327 return_status = -EIO;
4328 break;
4329 case HCLGE_ETHERTYPE_KEY_CONFLICT:
4330 dev_err(&hdev->pdev->dev,
4331 "add mac ethertype failed for key conflict.\n");
4332 return_status = -EIO;
4333 break;
4334 default:
4335 dev_err(&hdev->pdev->dev,
4336 "add mac ethertype failed for undefined, code=%d.\n",
4337 resp_code);
4338 return_status = -EIO;
4339 }
4340
4341 return return_status;
4342}
4343
4344static int hclge_add_mgr_tbl(struct hclge_dev *hdev,
4345 const struct hclge_mac_mgr_tbl_entry_cmd *req)
4346{
4347 struct hclge_desc desc;
4348 u8 resp_code;
4349 u16 retval;
4350 int ret;
4351
4352 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_ETHTYPE_ADD, false);
4353 memcpy(desc.data, req, sizeof(struct hclge_mac_mgr_tbl_entry_cmd));
4354
4355 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
4356 if (ret) {
4357 dev_err(&hdev->pdev->dev,
4358 "add mac ethertype failed for cmd_send, ret =%d.\n",
4359 ret);
4360 return ret;
4361 }
4362
4363 resp_code = (le32_to_cpu(desc.data[0]) >> 8) & 0xff;
4364 retval = le16_to_cpu(desc.retval);
4365
4366 return hclge_get_mac_ethertype_cmd_status(hdev, retval, resp_code);
4367}
4368
4369static int init_mgr_tbl(struct hclge_dev *hdev)
4370{
4371 int ret;
4372 int i;
4373
4374 for (i = 0; i < ARRAY_SIZE(hclge_mgr_table); i++) {
4375 ret = hclge_add_mgr_tbl(hdev, &hclge_mgr_table[i]);
4376 if (ret) {
4377 dev_err(&hdev->pdev->dev,
4378 "add mac ethertype failed, ret =%d.\n",
4379 ret);
4380 return ret;
4381 }
4382 }
4383
4384 return 0;
4385}
4386
4252static void hclge_get_mac_addr(struct hnae3_handle *handle, u8 *p) 4387static void hclge_get_mac_addr(struct hnae3_handle *handle, u8 *p)
4253{ 4388{
4254 struct hclge_vport *vport = hclge_get_vport(handle); 4389 struct hclge_vport *vport = hclge_get_vport(handle);
@@ -5271,6 +5406,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
5271 return ret; 5406 return ret;
5272 } 5407 }
5273 5408
5409 ret = init_mgr_tbl(hdev);
5410 if (ret) {
5411 dev_err(&pdev->dev, "manager table init fail, ret =%d\n", ret);
5412 return ret;
5413 }
5414
5274 hclge_dcb_ops_set(hdev); 5415 hclge_dcb_ops_set(hdev);
5275 5416
5276 timer_setup(&hdev->service_timer, hclge_service_timer, 0); 5417 timer_setup(&hdev->service_timer, hclge_service_timer, 0);
@@ -5544,6 +5685,318 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num)
5544 return ret; 5685 return ret;
5545} 5686}
5546 5687
5688static int hclge_get_regs_num(struct hclge_dev *hdev, u32 *regs_num_32_bit,
5689 u32 *regs_num_64_bit)
5690{
5691 struct hclge_desc desc;
5692 u32 total_num;
5693 int ret;
5694
5695 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_REG_NUM, true);
5696 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
5697 if (ret) {
5698 dev_err(&hdev->pdev->dev,
5699 "Query register number cmd failed, ret = %d.\n", ret);
5700 return ret;
5701 }
5702
5703 *regs_num_32_bit = le32_to_cpu(desc.data[0]);
5704 *regs_num_64_bit = le32_to_cpu(desc.data[1]);
5705
5706 total_num = *regs_num_32_bit + *regs_num_64_bit;
5707 if (!total_num)
5708 return -EINVAL;
5709
5710 return 0;
5711}
5712
5713static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num,
5714 void *data)
5715{
5716#define HCLGE_32_BIT_REG_RTN_DATANUM 8
5717
5718 struct hclge_desc *desc;
5719 u32 *reg_val = data;
5720 __le32 *desc_data;
5721 int cmd_num;
5722 int i, k, n;
5723 int ret;
5724
5725 if (regs_num == 0)
5726 return 0;
5727
5728 cmd_num = DIV_ROUND_UP(regs_num + 2, HCLGE_32_BIT_REG_RTN_DATANUM);
5729 desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
5730 if (!desc)
5731 return -ENOMEM;
5732
5733 hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_32_BIT_REG, true);
5734 ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
5735 if (ret) {
5736 dev_err(&hdev->pdev->dev,
5737 "Query 32 bit register cmd failed, ret = %d.\n", ret);
5738 kfree(desc);
5739 return ret;
5740 }
5741
5742 for (i = 0; i < cmd_num; i++) {
5743 if (i == 0) {
5744 desc_data = (__le32 *)(&desc[i].data[0]);
5745 n = HCLGE_32_BIT_REG_RTN_DATANUM - 2;
5746 } else {
5747 desc_data = (__le32 *)(&desc[i]);
5748 n = HCLGE_32_BIT_REG_RTN_DATANUM;
5749 }
5750 for (k = 0; k < n; k++) {
5751 *reg_val++ = le32_to_cpu(*desc_data++);
5752
5753 regs_num--;
5754 if (!regs_num)
5755 break;
5756 }
5757 }
5758
5759 kfree(desc);
5760 return 0;
5761}
5762
5763static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num,
5764 void *data)
5765{
5766#define HCLGE_64_BIT_REG_RTN_DATANUM 4
5767
5768 struct hclge_desc *desc;
5769 u64 *reg_val = data;
5770 __le64 *desc_data;
5771 int cmd_num;
5772 int i, k, n;
5773 int ret;
5774
5775 if (regs_num == 0)
5776 return 0;
5777
5778 cmd_num = DIV_ROUND_UP(regs_num + 1, HCLGE_64_BIT_REG_RTN_DATANUM);
5779 desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL);
5780 if (!desc)
5781 return -ENOMEM;
5782
5783 hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QUERY_64_BIT_REG, true);
5784 ret = hclge_cmd_send(&hdev->hw, desc, cmd_num);
5785 if (ret) {
5786 dev_err(&hdev->pdev->dev,
5787 "Query 64 bit register cmd failed, ret = %d.\n", ret);
5788 kfree(desc);
5789 return ret;
5790 }
5791
5792 for (i = 0; i < cmd_num; i++) {
5793 if (i == 0) {
5794 desc_data = (__le64 *)(&desc[i].data[0]);
5795 n = HCLGE_64_BIT_REG_RTN_DATANUM - 1;
5796 } else {
5797 desc_data = (__le64 *)(&desc[i]);
5798 n = HCLGE_64_BIT_REG_RTN_DATANUM;
5799 }
5800 for (k = 0; k < n; k++) {
5801 *reg_val++ = le64_to_cpu(*desc_data++);
5802
5803 regs_num--;
5804 if (!regs_num)
5805 break;
5806 }
5807 }
5808
5809 kfree(desc);
5810 return 0;
5811}
5812
5813static int hclge_get_regs_len(struct hnae3_handle *handle)
5814{
5815 struct hclge_vport *vport = hclge_get_vport(handle);
5816 struct hclge_dev *hdev = vport->back;
5817 u32 regs_num_32_bit, regs_num_64_bit;
5818 int ret;
5819
5820 ret = hclge_get_regs_num(hdev, &regs_num_32_bit, &regs_num_64_bit);
5821 if (ret) {
5822 dev_err(&hdev->pdev->dev,
5823 "Get register number failed, ret = %d.\n", ret);
5824 return -EOPNOTSUPP;
5825 }
5826
5827 return regs_num_32_bit * sizeof(u32) + regs_num_64_bit * sizeof(u64);
5828}
5829
5830static void hclge_get_regs(struct hnae3_handle *handle, u32 *version,
5831 void *data)
5832{
5833 struct hclge_vport *vport = hclge_get_vport(handle);
5834 struct hclge_dev *hdev = vport->back;
5835 u32 regs_num_32_bit, regs_num_64_bit;
5836 int ret;
5837
5838 *version = hdev->fw_version;
5839
5840 ret = hclge_get_regs_num(hdev, &regs_num_32_bit, &regs_num_64_bit);
5841 if (ret) {
5842 dev_err(&hdev->pdev->dev,
5843 "Get register number failed, ret = %d.\n", ret);
5844 return;
5845 }
5846
5847 ret = hclge_get_32_bit_regs(hdev, regs_num_32_bit, data);
5848 if (ret) {
5849 dev_err(&hdev->pdev->dev,
5850 "Get 32 bit register failed, ret = %d.\n", ret);
5851 return;
5852 }
5853
5854 data = (u32 *)data + regs_num_32_bit;
5855 ret = hclge_get_64_bit_regs(hdev, regs_num_64_bit,
5856 data);
5857 if (ret)
5858 dev_err(&hdev->pdev->dev,
5859 "Get 64 bit register failed, ret = %d.\n", ret);
5860}
5861
5862static int hclge_set_led_status_sfp(struct hclge_dev *hdev, u8 speed_led_status,
5863 u8 act_led_status, u8 link_led_status,
5864 u8 locate_led_status)
5865{
5866 struct hclge_set_led_state_cmd *req;
5867 struct hclge_desc desc;
5868 int ret;
5869
5870 hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_LED_STATUS_CFG, false);
5871
5872 req = (struct hclge_set_led_state_cmd *)desc.data;
5873 hnae_set_field(req->port_speed_led_config, HCLGE_LED_PORT_SPEED_STATE_M,
5874 HCLGE_LED_PORT_SPEED_STATE_S, speed_led_status);
5875 hnae_set_field(req->link_led_config, HCLGE_LED_ACTIVITY_STATE_M,
5876 HCLGE_LED_ACTIVITY_STATE_S, act_led_status);
5877 hnae_set_field(req->activity_led_config, HCLGE_LED_LINK_STATE_M,
5878 HCLGE_LED_LINK_STATE_S, link_led_status);
5879 hnae_set_field(req->locate_led_config, HCLGE_LED_LOCATE_STATE_M,
5880 HCLGE_LED_LOCATE_STATE_S, locate_led_status);
5881
5882 ret = hclge_cmd_send(&hdev->hw, &desc, 1);
5883 if (ret)
5884 dev_err(&hdev->pdev->dev,
5885 "Send set led state cmd error, ret =%d\n", ret);
5886
5887 return ret;
5888}
5889
5890enum hclge_led_status {
5891 HCLGE_LED_OFF,
5892 HCLGE_LED_ON,
5893 HCLGE_LED_NO_CHANGE = 0xFF,
5894};
5895
5896static int hclge_set_led_id(struct hnae3_handle *handle,
5897 enum ethtool_phys_id_state status)
5898{
5899#define BLINK_FREQUENCY 2
5900 struct hclge_vport *vport = hclge_get_vport(handle);
5901 struct hclge_dev *hdev = vport->back;
5902 struct phy_device *phydev = hdev->hw.mac.phydev;
5903 int ret = 0;
5904
5905 if (phydev || hdev->hw.mac.media_type != HNAE3_MEDIA_TYPE_FIBER)
5906 return -EOPNOTSUPP;
5907
5908 switch (status) {
5909 case ETHTOOL_ID_ACTIVE:
5910 ret = hclge_set_led_status_sfp(hdev,
5911 HCLGE_LED_NO_CHANGE,
5912 HCLGE_LED_NO_CHANGE,
5913 HCLGE_LED_NO_CHANGE,
5914 HCLGE_LED_ON);
5915 break;
5916 case ETHTOOL_ID_INACTIVE:
5917 ret = hclge_set_led_status_sfp(hdev,
5918 HCLGE_LED_NO_CHANGE,
5919 HCLGE_LED_NO_CHANGE,
5920 HCLGE_LED_NO_CHANGE,
5921 HCLGE_LED_OFF);
5922 break;
5923 default:
5924 ret = -EINVAL;
5925 break;
5926 }
5927
5928 return ret;
5929}
5930
5931enum hclge_led_port_speed {
5932 HCLGE_SPEED_LED_FOR_1G,
5933 HCLGE_SPEED_LED_FOR_10G,
5934 HCLGE_SPEED_LED_FOR_25G,
5935 HCLGE_SPEED_LED_FOR_40G,
5936 HCLGE_SPEED_LED_FOR_50G,
5937 HCLGE_SPEED_LED_FOR_100G,
5938};
5939
5940static u8 hclge_led_get_speed_status(u32 speed)
5941{
5942 u8 speed_led;
5943
5944 switch (speed) {
5945 case HCLGE_MAC_SPEED_1G:
5946 speed_led = HCLGE_SPEED_LED_FOR_1G;
5947 break;
5948 case HCLGE_MAC_SPEED_10G:
5949 speed_led = HCLGE_SPEED_LED_FOR_10G;
5950 break;
5951 case HCLGE_MAC_SPEED_25G:
5952 speed_led = HCLGE_SPEED_LED_FOR_25G;
5953 break;
5954 case HCLGE_MAC_SPEED_40G:
5955 speed_led = HCLGE_SPEED_LED_FOR_40G;
5956 break;
5957 case HCLGE_MAC_SPEED_50G:
5958 speed_led = HCLGE_SPEED_LED_FOR_50G;
5959 break;
5960 case HCLGE_MAC_SPEED_100G:
5961 speed_led = HCLGE_SPEED_LED_FOR_100G;
5962 break;
5963 default:
5964 speed_led = HCLGE_LED_NO_CHANGE;
5965 }
5966
5967 return speed_led;
5968}
5969
5970static int hclge_update_led_status(struct hclge_dev *hdev)
5971{
5972 u8 port_speed_status, link_status, activity_status;
5973 u64 rx_pkts, tx_pkts;
5974
5975 if (hdev->hw.mac.media_type != HNAE3_MEDIA_TYPE_FIBER)
5976 return 0;
5977
5978 port_speed_status = hclge_led_get_speed_status(hdev->hw.mac.speed);
5979
5980 rx_pkts = hdev->hw_stats.mac_stats.mac_rx_total_pkt_num;
5981 tx_pkts = hdev->hw_stats.mac_stats.mac_tx_total_pkt_num;
5982 if (rx_pkts != hdev->rx_pkts_for_led ||
5983 tx_pkts != hdev->tx_pkts_for_led)
5984 activity_status = HCLGE_LED_ON;
5985 else
5986 activity_status = HCLGE_LED_OFF;
5987 hdev->rx_pkts_for_led = rx_pkts;
5988 hdev->tx_pkts_for_led = tx_pkts;
5989
5990 if (hdev->hw.mac.link)
5991 link_status = HCLGE_LED_ON;
5992 else
5993 link_status = HCLGE_LED_OFF;
5994
5995 return hclge_set_led_status_sfp(hdev, port_speed_status,
5996 activity_status, link_status,
5997 HCLGE_LED_NO_CHANGE);
5998}
5999
5547static const struct hnae3_ae_ops hclge_ops = { 6000static const struct hnae3_ae_ops hclge_ops = {
5548 .init_ae_dev = hclge_init_ae_dev, 6001 .init_ae_dev = hclge_init_ae_dev,
5549 .uninit_ae_dev = hclge_uninit_ae_dev, 6002 .uninit_ae_dev = hclge_uninit_ae_dev,
@@ -5595,6 +6048,9 @@ static const struct hnae3_ae_ops hclge_ops = {
5595 .set_channels = hclge_set_channels, 6048 .set_channels = hclge_set_channels,
5596 .get_channels = hclge_get_channels, 6049 .get_channels = hclge_get_channels,
5597 .get_flowctrl_adv = hclge_get_flowctrl_adv, 6050 .get_flowctrl_adv = hclge_get_flowctrl_adv,
6051 .get_regs_len = hclge_get_regs_len,
6052 .get_regs = hclge_get_regs,
6053 .set_led_id = hclge_set_led_id,
5598}; 6054};
5599 6055
5600static struct hnae3_ae_algo ae_algo = { 6056static struct hnae3_ae_algo ae_algo = {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index eeb6c8d66e4e..d99a76a9557c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -550,6 +550,9 @@ struct hclge_dev {
550 bool accept_mta_mc; /* Whether accept mta filter multicast */ 550 bool accept_mta_mc; /* Whether accept mta filter multicast */
551 551
552 struct hclge_vlan_type_cfg vlan_type_cfg; 552 struct hclge_vlan_type_cfg vlan_type_cfg;
553
554 u64 rx_pkts_for_led;
555 u64 tx_pkts_for_led;
553}; 556};
554 557
555/* VPort level vlan tag configuration for TX direction */ 558/* VPort level vlan tag configuration for TX direction */