Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: hns3: support wake on lan configuration and query

The HNS3 driver supports Wake-on-LAN, which can wake up
the server from power off state to power on state by magic
packet or magic security packet.

ChangeLog:
v1->v2:
Deleted the debugfs function that overlaps with the ethtool function
from suggestion of Andrew Lunn.

v2->v3:
Return the wol configuration stored in driver,
suggested by Alexander H Duyck.

v3->v4:
Add a helper to go from netdev to the local struct,
suggested by Simon Horman and Jakub Kicinski.

Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: Hao Lan <lanhao@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Hao Lan and committed by
David S. Miller
3b064f54 be435af5

+202
+12
drivers/net/ethernet/hisilicon/hns3/hnae3.h
··· 100 100 HNAE3_DEV_SUPPORT_CQ_B, 101 101 HNAE3_DEV_SUPPORT_FEC_STATS_B, 102 102 HNAE3_DEV_SUPPORT_LANE_NUM_B, 103 + HNAE3_DEV_SUPPORT_WOL_B, 103 104 }; 104 105 105 106 #define hnae3_ae_dev_fd_supported(ae_dev) \ ··· 168 167 169 168 #define hnae3_ae_dev_lane_num_supported(ae_dev) \ 170 169 test_bit(HNAE3_DEV_SUPPORT_LANE_NUM_B, (ae_dev)->caps) 170 + 171 + #define hnae3_ae_dev_wol_supported(ae_dev) \ 172 + test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) 171 173 172 174 enum HNAE3_PF_CAP_BITS { 173 175 HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, ··· 565 561 * Get phc info 566 562 * clean_vf_config 567 563 * Clean residual vf info after disable sriov 564 + * get_wol 565 + * Get wake on lan info 566 + * set_wol 567 + * Config wake on lan 568 568 */ 569 569 struct hnae3_ae_ops { 570 570 int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev); ··· 768 760 void (*clean_vf_config)(struct hnae3_ae_dev *ae_dev, int num_vfs); 769 761 int (*get_dscp_prio)(struct hnae3_handle *handle, u8 dscp, 770 762 u8 *tc_map_mode, u8 *priority); 763 + void (*get_wol)(struct hnae3_handle *handle, 764 + struct ethtool_wolinfo *wol); 765 + int (*set_wol)(struct hnae3_handle *handle, 766 + struct ethtool_wolinfo *wol); 771 767 }; 772 768 773 769 struct hnae3_dcb_ops {
+1
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c
··· 155 155 {HCLGE_COMM_CAP_FD_B, HNAE3_DEV_SUPPORT_FD_B}, 156 156 {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B}, 157 157 {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, 158 + {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, 158 159 }; 159 160 160 161 static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = {
+3
drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h
··· 294 294 HCLGE_PPP_CMD0_INT_CMD = 0x2100, 295 295 HCLGE_PPP_CMD1_INT_CMD = 0x2101, 296 296 HCLGE_MAC_ETHERTYPE_IDX_RD = 0x2105, 297 + HCLGE_OPC_WOL_GET_SUPPORTED_MODE = 0x2201, 298 + HCLGE_OPC_WOL_CFG = 0x2202, 297 299 HCLGE_NCSI_INT_EN = 0x2401, 298 300 299 301 /* ROH MAC commands */ ··· 347 345 HCLGE_COMM_CAP_FD_B = 21, 348 346 HCLGE_COMM_CAP_FEC_STATS_B = 25, 349 347 HCLGE_COMM_CAP_LANE_NUM_B = 27, 348 + HCLGE_COMM_CAP_WOL_B = 28, 350 349 }; 351 350 352 351 enum HCLGE_COMM_API_CAP_BITS {
+3
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
··· 408 408 }, { 409 409 .name = "support lane num", 410 410 .cap_bit = HNAE3_DEV_SUPPORT_LANE_NUM_B, 411 + }, { 412 + .name = "support wake on lan", 413 + .cap_bit = HNAE3_DEV_SUPPORT_WOL_B, 411 414 } 412 415 }; 413 416
+6
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
··· 695 695 #define hns3_get_handle(ndev) \ 696 696 (((struct hns3_nic_priv *)netdev_priv(ndev))->ae_handle) 697 697 698 + #define hns3_get_ae_dev(handle) \ 699 + (pci_get_drvdata((handle)->pdev)) 700 + 701 + #define hns3_get_ops(handle) \ 702 + ((handle)->ae_algo->ops) 703 + 698 704 #define hns3_gl_usec_to_reg(int_gl) ((int_gl) >> 1) 699 705 #define hns3_gl_round_down(int_gl) round_down(int_gl, 2) 700 706
+27
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
··· 2063 2063 return -ENODATA; 2064 2064 } 2065 2065 2066 + static void hns3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) 2067 + { 2068 + struct hnae3_handle *handle = hns3_get_handle(netdev); 2069 + const struct hnae3_ae_ops *ops = hns3_get_ops(handle); 2070 + struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(handle); 2071 + 2072 + if (!hnae3_ae_dev_wol_supported(ae_dev)) 2073 + return; 2074 + 2075 + ops->get_wol(handle, wol); 2076 + } 2077 + 2078 + static int hns3_set_wol(struct net_device *netdev, 2079 + struct ethtool_wolinfo *wol) 2080 + { 2081 + struct hnae3_handle *handle = hns3_get_handle(netdev); 2082 + const struct hnae3_ae_ops *ops = hns3_get_ops(handle); 2083 + struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(handle); 2084 + 2085 + if (!hnae3_ae_dev_wol_supported(ae_dev)) 2086 + return -EOPNOTSUPP; 2087 + 2088 + return ops->set_wol(handle, wol); 2089 + } 2090 + 2066 2091 static const struct ethtool_ops hns3vf_ethtool_ops = { 2067 2092 .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, 2068 2093 .supported_ring_params = HNS3_ETHTOOL_RING, ··· 2164 2139 .set_tunable = hns3_set_tunable, 2165 2140 .reset = hns3_set_reset, 2166 2141 .get_link_ext_state = hns3_get_link_ext_state, 2142 + .get_wol = hns3_get_wol, 2143 + .set_wol = hns3_set_wol, 2167 2144 }; 2168 2145 2169 2146 void hns3_ethtool_set_ops(struct net_device *netdev)
+12
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
··· 872 872 u8 rsv1[18]; 873 873 }; 874 874 875 + struct hclge_wol_cfg_cmd { 876 + __le32 wake_on_lan_mode; 877 + u8 sopass[SOPASS_MAX]; 878 + u8 sopass_size; 879 + u8 rsv[13]; 880 + }; 881 + 882 + struct hclge_query_wol_supported_cmd { 883 + __le32 supported_wake_mode; 884 + u8 rsv[20]; 885 + }; 886 + 875 887 struct hclge_hw; 876 888 int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num); 877 889 enum hclge_comm_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw,
+130
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
··· 11522 11522 hclge_write_dev(&hdev->hw, HCLGE_RXD_ADV_LAYOUT_EN_REG, 0); 11523 11523 } 11524 11524 11525 + static struct hclge_wol_info *hclge_get_wol_info(struct hnae3_handle *handle) 11526 + { 11527 + struct hclge_vport *vport = hclge_get_vport(handle); 11528 + 11529 + return &vport->back->hw.mac.wol; 11530 + } 11531 + 11532 + static int hclge_get_wol_supported_mode(struct hclge_dev *hdev, 11533 + u32 *wol_supported) 11534 + { 11535 + struct hclge_query_wol_supported_cmd *wol_supported_cmd; 11536 + struct hclge_desc desc; 11537 + int ret; 11538 + 11539 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_GET_SUPPORTED_MODE, 11540 + true); 11541 + wol_supported_cmd = (struct hclge_query_wol_supported_cmd *)desc.data; 11542 + 11543 + ret = hclge_cmd_send(&hdev->hw, &desc, 1); 11544 + if (ret) { 11545 + dev_err(&hdev->pdev->dev, 11546 + "failed to query wol supported, ret = %d\n", ret); 11547 + return ret; 11548 + } 11549 + 11550 + *wol_supported = le32_to_cpu(wol_supported_cmd->supported_wake_mode); 11551 + 11552 + return 0; 11553 + } 11554 + 11555 + static int hclge_set_wol_cfg(struct hclge_dev *hdev, 11556 + struct hclge_wol_info *wol_info) 11557 + { 11558 + struct hclge_wol_cfg_cmd *wol_cfg_cmd; 11559 + struct hclge_desc desc; 11560 + int ret; 11561 + 11562 + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_CFG, false); 11563 + wol_cfg_cmd = (struct hclge_wol_cfg_cmd *)desc.data; 11564 + wol_cfg_cmd->wake_on_lan_mode = cpu_to_le32(wol_info->wol_current_mode); 11565 + wol_cfg_cmd->sopass_size = wol_info->wol_sopass_size; 11566 + memcpy(wol_cfg_cmd->sopass, wol_info->wol_sopass, SOPASS_MAX); 11567 + 11568 + ret = hclge_cmd_send(&hdev->hw, &desc, 1); 11569 + if (ret) 11570 + dev_err(&hdev->pdev->dev, 11571 + "failed to set wol config, ret = %d\n", ret); 11572 + 11573 + return ret; 11574 + } 11575 + 11576 + static int hclge_update_wol(struct hclge_dev *hdev) 11577 + { 11578 + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; 11579 + 11580 + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) 11581 + return 0; 11582 + 11583 + return hclge_set_wol_cfg(hdev, wol_info); 11584 + } 11585 + 11586 + static int hclge_init_wol(struct hclge_dev *hdev) 11587 + { 11588 + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; 11589 + int ret; 11590 + 11591 + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) 11592 + return 0; 11593 + 11594 + memset(wol_info, 0, sizeof(struct hclge_wol_info)); 11595 + ret = hclge_get_wol_supported_mode(hdev, 11596 + &wol_info->wol_support_mode); 11597 + if (ret) { 11598 + wol_info->wol_support_mode = 0; 11599 + return ret; 11600 + } 11601 + 11602 + return hclge_update_wol(hdev); 11603 + } 11604 + 11605 + static void hclge_get_wol(struct hnae3_handle *handle, 11606 + struct ethtool_wolinfo *wol) 11607 + { 11608 + struct hclge_wol_info *wol_info = hclge_get_wol_info(handle); 11609 + 11610 + wol->supported = wol_info->wol_support_mode; 11611 + wol->wolopts = wol_info->wol_current_mode; 11612 + if (wol_info->wol_current_mode & WAKE_MAGICSECURE) 11613 + memcpy(wol->sopass, wol_info->wol_sopass, SOPASS_MAX); 11614 + } 11615 + 11616 + static int hclge_set_wol(struct hnae3_handle *handle, 11617 + struct ethtool_wolinfo *wol) 11618 + { 11619 + struct hclge_wol_info *wol_info = hclge_get_wol_info(handle); 11620 + struct hclge_vport *vport = hclge_get_vport(handle); 11621 + u32 wol_mode; 11622 + int ret; 11623 + 11624 + wol_mode = wol->wolopts; 11625 + if (wol_mode & ~wol_info->wol_support_mode) 11626 + return -EINVAL; 11627 + 11628 + wol_info->wol_current_mode = wol_mode; 11629 + if (wol_mode & WAKE_MAGICSECURE) { 11630 + memcpy(wol_info->wol_sopass, wol->sopass, SOPASS_MAX); 11631 + wol_info->wol_sopass_size = SOPASS_MAX; 11632 + } else { 11633 + wol_info->wol_sopass_size = 0; 11634 + } 11635 + 11636 + ret = hclge_set_wol_cfg(vport->back, wol_info); 11637 + if (ret) 11638 + wol_info->wol_current_mode = 0; 11639 + 11640 + return ret; 11641 + } 11642 + 11525 11643 static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) 11526 11644 { 11527 11645 struct pci_dev *pdev = ae_dev->pdev; ··· 11835 11717 11836 11718 /* Enable MISC vector(vector0) */ 11837 11719 hclge_enable_vector(&hdev->misc_vector, true); 11720 + 11721 + ret = hclge_init_wol(hdev); 11722 + if (ret) 11723 + dev_warn(&pdev->dev, 11724 + "failed to wake on lan init, ret = %d\n", ret); 11838 11725 11839 11726 hclge_state_init(hdev); 11840 11727 hdev->last_reset_time = jiffies; ··· 12218 12095 return ret; 12219 12096 12220 12097 hclge_init_rxd_adv_layout(hdev); 12098 + 12099 + ret = hclge_update_wol(hdev); 12100 + if (ret) 12101 + dev_warn(&pdev->dev, 12102 + "failed to update wol config, ret = %d\n", ret); 12221 12103 12222 12104 dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n", 12223 12105 HCLGE_DRIVER_NAME); ··· 13270 13142 .get_link_diagnosis_info = hclge_get_link_diagnosis_info, 13271 13143 .clean_vf_config = hclge_clean_vport_config, 13272 13144 .get_dscp_prio = hclge_get_dscp_prio, 13145 + .get_wol = hclge_get_wol, 13146 + .set_wol = hclge_set_wol, 13273 13147 }; 13274 13148 13275 13149 static struct hnae3_ae_algo ae_algo = {
+8
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
··· 249 249 #define QUERY_SFP_SPEED 0 250 250 #define QUERY_ACTIVE_SPEED 1 251 251 252 + struct hclge_wol_info { 253 + u32 wol_support_mode; /* store the wake on lan info */ 254 + u32 wol_current_mode; 255 + u8 wol_sopass[SOPASS_MAX]; 256 + u8 wol_sopass_size; 257 + }; 258 + 252 259 struct hclge_mac { 253 260 u8 mac_id; 254 261 u8 phy_addr; ··· 275 268 u32 user_fec_mode; 276 269 u32 fec_ability; 277 270 int link; /* store the link status of mac & phy (if phy exists) */ 271 + struct hclge_wol_info wol; 278 272 struct phy_device *phydev; 279 273 struct mii_bus *mdio_bus; 280 274 phy_interface_t phy_if;