diff options
author | David S. Miller <davem@davemloft.net> | 2018-01-22 16:05:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-22 16:05:50 -0500 |
commit | 3dff4c621f687fe34d6cef2a331cd386a562376e (patch) | |
tree | 2d0f0bcfde73b983527d1f4edfeac8217b78bd0f | |
parent | b2d3bcfa26a7a8de41f358a6cae8b848673b3c6e (diff) | |
parent | 716aaac1f3f3ee141f550d2d6d7934eab42c1c29 (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>
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 | ||
409 | struct hnae3_dcb_ops { | 412 | struct 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 | ||
1066 | static 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 | |||
1076 | static 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 | |||
1087 | static 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 | |||
1066 | static const struct ethtool_ops hns3vf_ethtool_ops = { | 1098 | static 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 | ||
1108 | void hns3_ethtool_set_ops(struct net_device *netdev) | 1143 | void 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 | |||
617 | struct 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 | |||
823 | struct 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 | |||
784 | int hclge_cmd_init(struct hclge_dev *hdev); | 831 | int hclge_cmd_init(struct hclge_dev *hdev); |
785 | static inline void hclge_write_reg(void __iomem *base, u32 reg, u32 value) | 832 | static 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, | |||
39 | static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu); | 39 | static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu); |
40 | static int hclge_init_vlan_config(struct hclge_dev *hdev); | 40 | static int hclge_init_vlan_config(struct hclge_dev *hdev); |
41 | static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev); | 41 | static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev); |
42 | static int hclge_update_led_status(struct hclge_dev *hdev); | ||
42 | 43 | ||
43 | static struct hnae3_ae_algo ae_algo; | 44 | static 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 | ||
396 | static 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 | |||
395 | static int hclge_64_bit_update_stats(struct hclge_dev *hdev) | 406 | static 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 | ||
509 | static 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 | |||
498 | static int hclge_mac_update_stats(struct hclge_dev *hdev) | 541 | static 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 | ||
4302 | static 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 | |||
4344 | static 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 | |||
4369 | static 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 | |||
4252 | static void hclge_get_mac_addr(struct hnae3_handle *handle, u8 *p) | 4387 | static 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 | ||
5688 | static 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 | |||
5713 | static 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 | |||
5763 | static 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 | |||
5813 | static 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, ®s_num_32_bit, ®s_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 | |||
5830 | static 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, ®s_num_32_bit, ®s_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 | |||
5862 | static 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 | |||
5890 | enum hclge_led_status { | ||
5891 | HCLGE_LED_OFF, | ||
5892 | HCLGE_LED_ON, | ||
5893 | HCLGE_LED_NO_CHANGE = 0xFF, | ||
5894 | }; | ||
5895 | |||
5896 | static 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 | |||
5931 | enum 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 | |||
5940 | static 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 | |||
5970 | static 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 | |||
5547 | static const struct hnae3_ae_ops hclge_ops = { | 6000 | static 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 | ||
5600 | static struct hnae3_ae_algo ae_algo = { | 6056 | static 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 */ |