* [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 @ 2023-01-04 1:34 Hao Lan 2023-01-04 1:34 ` [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query Hao Lan 2023-01-04 1:34 ` [PATCH net-next 2/2] net: hns3: support debugfs for wake on lan Hao Lan 0 siblings, 2 replies; 8+ messages in thread From: Hao Lan @ 2023-01-04 1:34 UTC (permalink / raw) To: davem, kuba Cc: yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev HNS3 (HiSilicon Network System 3) supports Wake-on-LAN, magic mode and magic security mode on each pf. This patch supports the ethtool LAN wake-up configuration and query interfaces and debugfs query interfaces. It does not support the suspend resume interface because there is no corresponding application scenario. Hao Lan (2): net: hns3: support wake on lan configuration and query net: hns3: support debugfs for wake on lan drivers/net/ethernet/hisilicon/hns3/hnae3.h | 13 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 3 + .../ethernet/hisilicon/hns3/hns3_debugfs.c | 10 + .../ethernet/hisilicon/hns3/hns3_ethtool.c | 27 +++ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 24 ++ .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 62 ++++++ .../hisilicon/hns3/hns3pf/hclge_main.c | 206 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_main.h | 10 + 9 files changed, 356 insertions(+) -- 2.30.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query 2023-01-04 1:34 [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 Hao Lan @ 2023-01-04 1:34 ` Hao Lan 2023-01-04 2:10 ` Andrew Lunn 2023-01-04 1:34 ` [PATCH net-next 2/2] net: hns3: support debugfs for wake on lan Hao Lan 1 sibling, 1 reply; 8+ messages in thread From: Hao Lan @ 2023-01-04 1:34 UTC (permalink / raw) To: davem, kuba Cc: yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev Implement configuration and query WOL by ethtool and added the needed device commands and structures to hns3. Add it do not support suspend resume interface. Signed-off-by: Hao Lan <lanhao@huawei.com> --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 12 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 3 + .../ethernet/hisilicon/hns3/hns3_ethtool.c | 27 +++ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 26 +++ .../hisilicon/hns3/hns3pf/hclge_main.c | 204 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_main.h | 10 + 7 files changed, 283 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 17137de9338c..312ac1cccd39 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -99,6 +99,7 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_CQ_B, HNAE3_DEV_SUPPORT_FEC_STATS_B, HNAE3_DEV_SUPPORT_LANE_NUM_B, + HNAE3_DEV_SUPPORT_WOL_B, }; #define hnae3_ae_dev_fd_supported(ae_dev) \ @@ -167,6 +168,9 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_lane_num_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_LANE_NUM_B, (ae_dev)->caps) +#define hnae3_ae_dev_wol_supported(ae_dev) \ + test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) + enum HNAE3_PF_CAP_BITS { HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, }; @@ -560,6 +564,10 @@ struct hnae3_ae_dev { * Get phc info * clean_vf_config * Clean residual vf info after disable sriov + * get_wol + * Get wake on lan info + * set_wol + * Config wake on lan */ struct hnae3_ae_ops { int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev); @@ -759,6 +767,10 @@ struct hnae3_ae_ops { void (*clean_vf_config)(struct hnae3_ae_dev *ae_dev, int num_vfs); int (*get_dscp_prio)(struct hnae3_handle *handle, u8 dscp, u8 *tc_map_mode, u8 *priority); + void (*get_wol)(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol); + int (*set_wol)(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol); }; struct hnae3_dcb_ops { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index f671a63cecde..cbbab5b2b402 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -155,6 +155,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_FD_B, HNAE3_DEV_SUPPORT_FD_B}, {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B}, {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, + {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, }; static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index b1f9383b418f..de72ecbfd5ad 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -294,6 +294,8 @@ enum hclge_opcode_type { HCLGE_PPP_CMD0_INT_CMD = 0x2100, HCLGE_PPP_CMD1_INT_CMD = 0x2101, HCLGE_MAC_ETHERTYPE_IDX_RD = 0x2105, + HCLGE_OPC_WOL_GET_SUPPORTED_MODE = 0x2201, + HCLGE_OPC_WOL_CFG = 0x2202, HCLGE_NCSI_INT_EN = 0x2401, /* ROH MAC commands */ @@ -345,6 +347,7 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_FD_B = 21, HCLGE_COMM_CAP_FEC_STATS_B = 25, HCLGE_COMM_CAP_LANE_NUM_B = 27, + HCLGE_COMM_CAP_WOL_B = 28, }; enum HCLGE_COMM_API_CAP_BITS { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 55306fe8a540..1bd95f04d327 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -2063,6 +2063,31 @@ static int hns3_get_link_ext_state(struct net_device *netdev, return -ENODATA; } +static void hns3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + 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; + + if (!hnae3_ae_dev_wol_supported(ae_dev) || !ops->get_wol) + return; + + ops->get_wol(handle, wol); +} + +static int hns3_set_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + 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; + + if (!hnae3_ae_dev_wol_supported(ae_dev) || !ops->set_wol) + return -EOPNOTSUPP; + + return ops->set_wol(handle, wol); +} + static const struct ethtool_ops hns3vf_ethtool_ops = { .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, .supported_ring_params = HNS3_ETHTOOL_RING, @@ -2139,6 +2164,8 @@ static const struct ethtool_ops hns3_ethtool_ops = { .set_tunable = hns3_set_tunable, .reset = hns3_set_reset, .get_link_ext_state = hns3_get_link_ext_state, + .get_wol = hns3_get_wol, + .set_wol = hns3_set_wol, }; 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 43cada51d8cb..e6e94dae1b1a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -872,6 +872,32 @@ struct hclge_phy_reg_cmd { u8 rsv1[18]; }; +enum HCLGE_WOL_MODE { + HCLGE_WOL_PHY = BIT(0), + HCLGE_WOL_UNICAST = BIT(1), + HCLGE_WOL_MULTICAST = BIT(2), + HCLGE_WOL_BROADCAST = BIT(3), + HCLGE_WOL_ARP = BIT(4), + HCLGE_WOL_MAGIC = BIT(5), + HCLGE_WOL_MAGICSECURED = BIT(6), + HCLGE_WOL_FILTER = BIT(7), + HCLGE_WOL_DISABLE = 0, +}; + +#define HCLGE_SOPASS_MAX 6 + +struct hclge_wol_cfg_cmd { + __le32 wake_on_lan_mode; + u8 sopass[HCLGE_SOPASS_MAX]; + u8 sopass_size; + u8 rsv[13]; +}; + +struct hclge_query_wol_supported_cmd { + __le32 supported_wake_mode; + u8 rsv[20]; +}; + struct hclge_hw; int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num); enum hclge_comm_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 4e54f91f7a6c..88cb5c05bc43 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -11500,6 +11500,201 @@ static void hclge_uninit_rxd_adv_layout(struct hclge_dev *hdev) hclge_write_dev(&hdev->hw, HCLGE_RXD_ADV_LAYOUT_EN_REG, 0); } +static __u32 hclge_wol_mode_to_ethtool(u32 mode) +{ + __u32 ret = 0; + + if (mode & HCLGE_WOL_PHY) + ret |= WAKE_PHY; + + if (mode & HCLGE_WOL_UNICAST) + ret |= WAKE_UCAST; + + if (mode & HCLGE_WOL_MULTICAST) + ret |= WAKE_MCAST; + + if (mode & HCLGE_WOL_BROADCAST) + ret |= WAKE_BCAST; + + if (mode & HCLGE_WOL_ARP) + ret |= WAKE_ARP; + + if (mode & HCLGE_WOL_MAGIC) + ret |= WAKE_MAGIC; + + if (mode & HCLGE_WOL_MAGICSECURED) + ret |= WAKE_MAGICSECURE; + + if (mode & HCLGE_WOL_FILTER) + ret |= WAKE_FILTER; + + return ret; +} + +static u32 hclge_wol_mode_from_ethtool(__u32 mode) +{ + u32 ret = HCLGE_WOL_DISABLE; + + if (mode & WAKE_PHY) + ret |= HCLGE_WOL_PHY; + + if (mode & WAKE_UCAST) + ret |= HCLGE_WOL_UNICAST; + + if (mode & WAKE_MCAST) + ret |= HCLGE_WOL_MULTICAST; + + if (mode & WAKE_BCAST) + ret |= HCLGE_WOL_BROADCAST; + + if (mode & WAKE_ARP) + ret |= HCLGE_WOL_ARP; + + if (mode & WAKE_MAGIC) + ret |= HCLGE_WOL_MAGIC; + + if (mode & WAKE_MAGICSECURE) + ret |= HCLGE_WOL_MAGICSECURED; + + if (mode & WAKE_FILTER) + ret |= HCLGE_WOL_FILTER; + + return ret; +} + +int hclge_get_wol_supported_mode(struct hclge_dev *hdev, u32 *wol_supported) +{ + struct hclge_query_wol_supported_cmd *wol_supported_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_GET_SUPPORTED_MODE, + true); + wol_supported_cmd = (struct hclge_query_wol_supported_cmd *)desc.data; + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to query wol supported, ret = %d\n", ret); + return ret; + } + + *wol_supported = le32_to_cpu(wol_supported_cmd->supported_wake_mode); + + return 0; +} + +int hclge_get_wol_cfg(struct hclge_dev *hdev, u32 *mode) +{ + struct hclge_wol_cfg_cmd *wol_cfg_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_CFG, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get wol config, ret = %d\n", ret); + return ret; + } + + wol_cfg_cmd = (struct hclge_wol_cfg_cmd *)desc.data; + *mode = le32_to_cpu(wol_cfg_cmd->wake_on_lan_mode); + + return 0; +} + +static int hclge_set_wol_cfg(struct hclge_dev *hdev, + struct hclge_wol_info *wol_info) +{ + struct hclge_wol_cfg_cmd *wol_cfg_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_CFG, false); + wol_cfg_cmd = (struct hclge_wol_cfg_cmd *)desc.data; + wol_cfg_cmd->wake_on_lan_mode = cpu_to_le32(wol_info->wol_current_mode); + wol_cfg_cmd->sopass_size = wol_info->wol_sopass_size; + memcpy(wol_cfg_cmd->sopass, wol_info->wol_sopass, HCLGE_SOPASS_MAX); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set wol config, ret = %d\n", ret); + + return ret; +} + +static int hclge_update_wol(struct hclge_dev *hdev) +{ + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) + return 0; + + return hclge_set_wol_cfg(hdev, wol_info); +} + +static int hclge_init_wol(struct hclge_dev *hdev) +{ + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + int ret; + + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) + return 0; + + memset(wol_info, 0, sizeof(struct hclge_wol_info)); + ret = hclge_get_wol_supported_mode(hdev, + &wol_info->wol_support_mode); + if (ret) { + wol_info->wol_support_mode = HCLGE_WOL_DISABLE; + return ret; + } + + return hclge_update_wol(hdev); +} + +static void hclge_get_wol(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + + wol->supported = hclge_wol_mode_to_ethtool(wol_info->wol_support_mode); + wol->wolopts = hclge_wol_mode_to_ethtool(wol_info->wol_current_mode); + if (wol_info->wol_current_mode & HCLGE_WOL_MAGICSECURED) + memcpy(wol->sopass, wol_info->wol_sopass, HCLGE_SOPASS_MAX); +} + +static int hclge_set_wol(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + u32 wol_mode; + int ret; + + wol_mode = hclge_wol_mode_from_ethtool(wol->wolopts); + if (wol_mode & ~wol_info->wol_support_mode) + return -EINVAL; + + wol_info->wol_current_mode = wol_mode; + if (wol_mode & HCLGE_WOL_MAGICSECURED) { + memcpy(wol_info->wol_sopass, wol->sopass, HCLGE_SOPASS_MAX); + wol_info->wol_sopass_size = HCLGE_SOPASS_MAX; + } else { + wol_info->wol_sopass_size = 0; + } + + ret = hclge_set_wol_cfg(hdev, wol_info); + if (ret) + wol_info->wol_current_mode = HCLGE_WOL_DISABLE; + + return ret; +} + static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) { struct pci_dev *pdev = ae_dev->pdev; @@ -11696,6 +11891,11 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) /* Enable MISC vector(vector0) */ hclge_enable_vector(&hdev->misc_vector, true); + ret = hclge_init_wol(hdev); + if (ret) + dev_warn(&pdev->dev, + "failed to wake on lan init, ret = %d\n", ret); + hclge_state_init(hdev); hdev->last_reset_time = jiffies; @@ -12075,6 +12275,8 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) hclge_init_rxd_adv_layout(hdev); + (void)hclge_update_wol(hdev); + dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n", HCLGE_DRIVER_NAME); @@ -13105,6 +13307,8 @@ static const struct hnae3_ae_ops hclge_ops = { .get_link_diagnosis_info = hclge_get_link_diagnosis_info, .clean_vf_config = hclge_clean_vport_config, .get_dscp_prio = hclge_get_dscp_prio, + .get_wol = hclge_get_wol, + .set_wol = hclge_set_wol, }; 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 495b639b0dc2..3be92ceb5744 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -249,6 +249,13 @@ enum HCLGE_MAC_DUPLEX { #define QUERY_SFP_SPEED 0 #define QUERY_ACTIVE_SPEED 1 +struct hclge_wol_info { + u32 wol_support_mode; /* store the wake on lan info */ + u32 wol_current_mode; + u8 wol_sopass[HCLGE_SOPASS_MAX]; + u8 wol_sopass_size; +}; + struct hclge_mac { u8 mac_id; u8 phy_addr; @@ -268,6 +275,7 @@ struct hclge_mac { u32 user_fec_mode; u32 fec_ability; int link; /* store the link status of mac & phy (if phy exists) */ + struct hclge_wol_info wol; struct phy_device *phydev; struct mii_bus *mdio_bus; phy_interface_t phy_if; @@ -1141,4 +1149,6 @@ int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len); int hclge_push_vf_link_status(struct hclge_vport *vport); int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en); int hclge_mac_update_stats(struct hclge_dev *hdev); +int hclge_get_wol_supported_mode(struct hclge_dev *hdev, u32 *wol_supported); +int hclge_get_wol_cfg(struct hclge_dev *hdev, u32 *mode); #endif -- 2.30.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query 2023-01-04 1:34 ` [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query Hao Lan @ 2023-01-04 2:10 ` Andrew Lunn 2023-01-04 12:57 ` Hao Lan 0 siblings, 1 reply; 8+ messages in thread From: Andrew Lunn @ 2023-01-04 2:10 UTC (permalink / raw) To: Hao Lan Cc: davem, kuba, yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev > +enum HCLGE_WOL_MODE { > + HCLGE_WOL_PHY = BIT(0), > + HCLGE_WOL_UNICAST = BIT(1), > + HCLGE_WOL_MULTICAST = BIT(2), > + HCLGE_WOL_BROADCAST = BIT(3), > + HCLGE_WOL_ARP = BIT(4), > + HCLGE_WOL_MAGIC = BIT(5), > + HCLGE_WOL_MAGICSECURED = BIT(6), > + HCLGE_WOL_FILTER = BIT(7), > + HCLGE_WOL_DISABLE = 0, > +}; These are the exact same values as WAKE_PHY, WAKE_CAST etc. Since they are ABI, they will never change. So you may as well throw these away and just use the Linux values. > struct hclge_hw; > int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num); > enum hclge_comm_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw, > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > index 4e54f91f7a6c..88cb5c05bc43 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > @@ -11500,6 +11500,201 @@ static void hclge_uninit_rxd_adv_layout(struct hclge_dev *hdev) > hclge_write_dev(&hdev->hw, HCLGE_RXD_ADV_LAYOUT_EN_REG, 0); > } > > +static __u32 hclge_wol_mode_to_ethtool(u32 mode) > +{ > + __u32 ret = 0; > + > + if (mode & HCLGE_WOL_PHY) > + ret |= WAKE_PHY; > + > + if (mode & HCLGE_WOL_UNICAST) > + ret |= WAKE_UCAST; > + > + if (mode & HCLGE_WOL_MULTICAST) > + ret |= WAKE_MCAST; > + > + if (mode & HCLGE_WOL_BROADCAST) > + ret |= WAKE_BCAST; > + > + if (mode & HCLGE_WOL_ARP) > + ret |= WAKE_ARP; > + > + if (mode & HCLGE_WOL_MAGIC) > + ret |= WAKE_MAGIC; > + > + if (mode & HCLGE_WOL_MAGICSECURED) > + ret |= WAKE_MAGICSECURE; > + > + if (mode & HCLGE_WOL_FILTER) > + ret |= WAKE_FILTER; Once you throw away HCLGE_WOL_*, this function becomes much simpler. > + > + return ret; > +} > + > +static u32 hclge_wol_mode_from_ethtool(__u32 mode) > +{ > + u32 ret = HCLGE_WOL_DISABLE; > + > + if (mode & WAKE_PHY) > + ret |= HCLGE_WOL_PHY; > + > + if (mode & WAKE_UCAST) > + ret |= HCLGE_WOL_UNICAST; This one two. > @@ -12075,6 +12275,8 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) > > hclge_init_rxd_adv_layout(hdev); > > + (void)hclge_update_wol(hdev); Please avoid casts like this. If there is an error, you should not ignore it. If it cannot fail, make it a void function. Andrew ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query 2023-01-04 2:10 ` Andrew Lunn @ 2023-01-04 12:57 ` Hao Lan 2023-01-04 15:00 ` Andrew Lunn 0 siblings, 1 reply; 8+ messages in thread From: Hao Lan @ 2023-01-04 12:57 UTC (permalink / raw) To: Andrew Lunn Cc: davem, kuba, yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev Hi Andrew, Thank you for reviewing our code. Thank you very much. You're right, such as WAKE_PHY, WAKE_CAST, these are implemented in the kernel, they are ABI, they will never change, we use it will directly simplify our code, your advice is very useful, thank you very much for your advice. However, these interfaces serve as a buffer between our firmware and the linux community. Considering our interface expansion and evolution, we may add some private modes in the future. If the Linux community does not accept our private modes, we will not be able to carry out these work. So please let us keep enum HCLGE_WOL_MODE, thank you. Best regards, Hao Lan On 2023/1/4 10:10, Andrew Lunn wrote: >> +enum HCLGE_WOL_MODE { >> + HCLGE_WOL_PHY = BIT(0), >> + HCLGE_WOL_UNICAST = BIT(1), >> + HCLGE_WOL_MULTICAST = BIT(2), >> + HCLGE_WOL_BROADCAST = BIT(3), >> + HCLGE_WOL_ARP = BIT(4), >> + HCLGE_WOL_MAGIC = BIT(5), >> + HCLGE_WOL_MAGICSECURED = BIT(6), >> + HCLGE_WOL_FILTER = BIT(7), >> + HCLGE_WOL_DISABLE = 0, >> +}; > > These are the exact same values as WAKE_PHY, WAKE_CAST etc. Since they > are ABI, they will never change. So you may as well throw these away > and just use the Linux values. > >> struct hclge_hw; >> int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num); >> enum hclge_comm_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw, >> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c >> index 4e54f91f7a6c..88cb5c05bc43 100644 >> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c >> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c >> @@ -11500,6 +11500,201 @@ static void hclge_uninit_rxd_adv_layout(struct hclge_dev *hdev) >> hclge_write_dev(&hdev->hw, HCLGE_RXD_ADV_LAYOUT_EN_REG, 0); >> } >> >> +static __u32 hclge_wol_mode_to_ethtool(u32 mode) >> +{ >> + __u32 ret = 0; >> + >> + if (mode & HCLGE_WOL_PHY) >> + ret |= WAKE_PHY; >> + >> + if (mode & HCLGE_WOL_UNICAST) >> + ret |= WAKE_UCAST; >> + >> + if (mode & HCLGE_WOL_MULTICAST) >> + ret |= WAKE_MCAST; >> + >> + if (mode & HCLGE_WOL_BROADCAST) >> + ret |= WAKE_BCAST; >> + >> + if (mode & HCLGE_WOL_ARP) >> + ret |= WAKE_ARP; >> + >> + if (mode & HCLGE_WOL_MAGIC) >> + ret |= WAKE_MAGIC; >> + >> + if (mode & HCLGE_WOL_MAGICSECURED) >> + ret |= WAKE_MAGICSECURE; >> + >> + if (mode & HCLGE_WOL_FILTER) >> + ret |= WAKE_FILTER; > > Once you throw away HCLGE_WOL_*, this function becomes much simpler. > >> + >> + return ret; >> +} >> + >> +static u32 hclge_wol_mode_from_ethtool(__u32 mode) >> +{ >> + u32 ret = HCLGE_WOL_DISABLE; >> + >> + if (mode & WAKE_PHY) >> + ret |= HCLGE_WOL_PHY; >> + >> + if (mode & WAKE_UCAST) >> + ret |= HCLGE_WOL_UNICAST; > > This one two. > >> @@ -12075,6 +12275,8 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) >> >> hclge_init_rxd_adv_layout(hdev); >> >> + (void)hclge_update_wol(hdev); > > Please avoid casts like this. If there is an error, you should not > ignore it. If it cannot fail, make it a void function. > > Andrew > . > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query 2023-01-04 12:57 ` Hao Lan @ 2023-01-04 15:00 ` Andrew Lunn 0 siblings, 0 replies; 8+ messages in thread From: Andrew Lunn @ 2023-01-04 15:00 UTC (permalink / raw) To: Hao Lan Cc: davem, kuba, yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev On Wed, Jan 04, 2023 at 08:57:40PM +0800, Hao Lan wrote: > Hi Andrew, > Thank you for reviewing our code. Thank you very much. > You're right, such as WAKE_PHY, WAKE_CAST, these are implemented > in the kernel, they are ABI, they will never change, we use it > will directly simplify our code, your advice is very useful, thank > you very much for your advice. > However, these interfaces serve as a buffer between our firmware > and the linux community. Considering our interface expansion and > evolution, we may add some private modes in the future. You cannot add private WOL modes, since they will be unusable without ethtool support. And to add ethtool support, they need to be public. And to make them public, you just add more WAKE_ macros. Just make sure the new modes you add are well described, so other drivers can also implement them. Andrew ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 2/2] net: hns3: support debugfs for wake on lan 2023-01-04 1:34 [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 Hao Lan 2023-01-04 1:34 ` [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query Hao Lan @ 2023-01-04 1:34 ` Hao Lan 2023-01-04 2:12 ` Andrew Lunn 1 sibling, 1 reply; 8+ messages in thread From: Hao Lan @ 2023-01-04 1:34 UTC (permalink / raw) To: davem, kuba Cc: yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev Implement debugfs for wake on lan to hns3. The debugfs support verify the firmware wake on lan configuration. Signed-off-by: Hao Lan <lanhao@huawei.com> --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + .../ethernet/hisilicon/hns3/hns3_debugfs.c | 10 +++ .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 62 +++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 312ac1cccd39..939308f8f472 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -321,6 +321,7 @@ enum hnae3_dbg_cmd { HNAE3_DBG_CMD_UMV_INFO, HNAE3_DBG_CMD_PAGE_POOL_INFO, HNAE3_DBG_CMD_COAL_INFO, + HNAE3_DBG_CMD_WOL_INFO, HNAE3_DBG_CMD_UNKNOWN, }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index 66feb23f7b7b..679a39aab801 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -357,6 +357,13 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { .buf_len = HNS3_DBG_READ_LEN_1MB, .init = hns3_dbg_common_file_init, }, + { + .name = "wol_info", + .cmd = HNAE3_DBG_CMD_WOL_INFO, + .dentry = HNS3_DBG_DENTRY_COMMON, + .buf_len = HNS3_DBG_READ_LEN, + .init = hns3_dbg_common_file_init, + }, }; static struct hns3_dbg_cap_info hns3_dbg_cap[] = { @@ -408,6 +415,9 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = { }, { .name = "support lane num", .cap_bit = HNAE3_DEV_SUPPORT_LANE_NUM_B, + }, { + .name = "support wake on lan", + .cap_bit = HNAE3_DEV_SUPPORT_WOL_B, } }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 142415c84c6b..fdbf031bcd49 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -2394,6 +2394,64 @@ static int hclge_dbg_dump_mac_mc(struct hclge_dev *hdev, char *buf, int len) return 0; } +static void hclge_dump_wol_mode(u32 mode, char *buf, int len, int *pos) +{ + if (mode & HCLGE_WOL_PHY) + *pos += scnprintf(buf + *pos, len - *pos, " [p]phy\n"); + + if (mode & HCLGE_WOL_UNICAST) + *pos += scnprintf(buf + *pos, len - *pos, " [u]unicast\n"); + + if (mode & HCLGE_WOL_MULTICAST) + *pos += scnprintf(buf + *pos, len - *pos, " [m]multicast\n"); + + if (mode & HCLGE_WOL_BROADCAST) + *pos += scnprintf(buf + *pos, len - *pos, " [b]broadcast\n"); + + if (mode & HCLGE_WOL_ARP) + *pos += scnprintf(buf + *pos, len - *pos, " [a]arp\n"); + + if (mode & HCLGE_WOL_MAGIC) + *pos += scnprintf(buf + *pos, len - *pos, " [g]magic\n"); + + if (mode & HCLGE_WOL_MAGICSECURED) + *pos += scnprintf(buf + *pos, len - *pos, + " [s]magic secured\n"); + + if (mode & HCLGE_WOL_FILTER) + *pos += scnprintf(buf + *pos, len - *pos, " [f]filter\n"); +} + +static int hclge_dbg_dump_wol_info(struct hclge_dev *hdev, char *buf, int len) +{ + u32 wol_supported; + int pos = 0; + u32 mode; + + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) { + pos += scnprintf(buf + pos, len - pos, + "wake-on-lan is unsupported\n"); + return 0; + } + + pos += scnprintf(buf + pos, len - pos, "wake-on-lan mode:\n"); + pos += scnprintf(buf + pos, len - pos, " supported:\n"); + if (hclge_get_wol_supported_mode(hdev, &wol_supported)) + return -EINVAL; + + hclge_dump_wol_mode(wol_supported, buf, len, &pos); + + pos += scnprintf(buf + pos, len - pos, " current:\n"); + if (hclge_get_wol_cfg(hdev, &mode)) + return -EINVAL; + if (mode) + hclge_dump_wol_mode(mode, buf, len, &pos); + else + pos += scnprintf(buf + pos, len - pos, " [d]disabled\n"); + + return 0; +} + static const struct hclge_dbg_func hclge_dbg_cmd_func[] = { { .cmd = HNAE3_DBG_CMD_TM_NODES, @@ -2543,6 +2601,10 @@ static const struct hclge_dbg_func hclge_dbg_cmd_func[] = { .cmd = HNAE3_DBG_CMD_UMV_INFO, .dbg_dump = hclge_dbg_dump_umv_info, }, + { + .cmd = HNAE3_DBG_CMD_WOL_INFO, + .dbg_dump = hclge_dbg_dump_wol_info, + }, }; int hclge_dbg_read_cmd(struct hnae3_handle *handle, enum hnae3_dbg_cmd cmd, -- 2.30.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next 2/2] net: hns3: support debugfs for wake on lan 2023-01-04 1:34 ` [PATCH net-next 2/2] net: hns3: support debugfs for wake on lan Hao Lan @ 2023-01-04 2:12 ` Andrew Lunn 0 siblings, 0 replies; 8+ messages in thread From: Andrew Lunn @ 2023-01-04 2:12 UTC (permalink / raw) To: Hao Lan Cc: davem, kuba, yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev On Wed, Jan 04, 2023 at 09:34:05AM +0800, Hao Lan wrote: > Implement debugfs for wake on lan to hns3. The debugfs > support verify the firmware wake on lan configuration. Is this actually needed, now you have verified the firmware? I can see it being a useful development tool, but now the feature is finished, the firmware is bug free, it is of no real use. Everybody will just use ethtool. Andrew ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 @ 2023-02-06 13:49 Hao Lan 2023-02-06 13:49 ` [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query Hao Lan 0 siblings, 1 reply; 8+ messages in thread From: Hao Lan @ 2023-02-06 13:49 UTC (permalink / raw) To: davem, kuba Cc: yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev HNS3 (HiSilicon Network System 3) supports Wake-on-LAN, magic mode and magic security mode on each pf. This patch supports the ethtool LAN wake-up configuration and query interfaces and debugfs query interfaces. It does not support the suspend resume interface because there is no corresponding application scenario. Hao Lan (2): net: hns3: support wake on lan configuration and query net: hns3: support debugfs for wake on lan drivers/net/ethernet/hisilicon/hns3/hnae3.h | 13 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 3 + .../ethernet/hisilicon/hns3/hns3_debugfs.c | 10 + .../ethernet/hisilicon/hns3/hns3_ethtool.c | 27 +++ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 24 ++ .../hisilicon/hns3/hns3pf/hclge_debugfs.c | 62 ++++++ .../hisilicon/hns3/hns3pf/hclge_main.c | 206 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_main.h | 10 + 9 files changed, 356 insertions(+) -- 2.30.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query 2023-02-06 13:49 [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 Hao Lan @ 2023-02-06 13:49 ` Hao Lan 0 siblings, 0 replies; 8+ messages in thread From: Hao Lan @ 2023-02-06 13:49 UTC (permalink / raw) To: davem, kuba Cc: yisen.zhuang, salil.mehta, edumazet, pabeni, richardcochran, shenjian15, netdev Implement configuration and query WOL by ethtool and added the needed device commands and structures to hns3. Add it do not support suspend resume interface. Signed-off-by: Hao Lan <lanhao@huawei.com> --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 12 ++ .../hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hns3/hns3_common/hclge_comm_cmd.h | 3 + .../ethernet/hisilicon/hns3/hns3_ethtool.c | 27 +++ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 26 +++ .../hisilicon/hns3/hns3pf/hclge_main.c | 204 ++++++++++++++++++ .../hisilicon/hns3/hns3pf/hclge_main.h | 10 + 7 files changed, 283 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 17137de9338c..312ac1cccd39 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -99,6 +99,7 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_CQ_B, HNAE3_DEV_SUPPORT_FEC_STATS_B, HNAE3_DEV_SUPPORT_LANE_NUM_B, + HNAE3_DEV_SUPPORT_WOL_B, }; #define hnae3_ae_dev_fd_supported(ae_dev) \ @@ -167,6 +168,9 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_lane_num_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_LANE_NUM_B, (ae_dev)->caps) +#define hnae3_ae_dev_wol_supported(ae_dev) \ + test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) + enum HNAE3_PF_CAP_BITS { HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, }; @@ -560,6 +564,10 @@ struct hnae3_ae_dev { * Get phc info * clean_vf_config * Clean residual vf info after disable sriov + * get_wol + * Get wake on lan info + * set_wol + * Config wake on lan */ struct hnae3_ae_ops { int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev); @@ -759,6 +767,10 @@ struct hnae3_ae_ops { void (*clean_vf_config)(struct hnae3_ae_dev *ae_dev, int num_vfs); int (*get_dscp_prio)(struct hnae3_handle *handle, u8 dscp, u8 *tc_map_mode, u8 *priority); + void (*get_wol)(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol); + int (*set_wol)(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol); }; struct hnae3_dcb_ops { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index f671a63cecde..cbbab5b2b402 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -155,6 +155,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_FD_B, HNAE3_DEV_SUPPORT_FD_B}, {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B}, {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, + {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, }; static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index b1f9383b418f..de72ecbfd5ad 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -294,6 +294,8 @@ enum hclge_opcode_type { HCLGE_PPP_CMD0_INT_CMD = 0x2100, HCLGE_PPP_CMD1_INT_CMD = 0x2101, HCLGE_MAC_ETHERTYPE_IDX_RD = 0x2105, + HCLGE_OPC_WOL_GET_SUPPORTED_MODE = 0x2201, + HCLGE_OPC_WOL_CFG = 0x2202, HCLGE_NCSI_INT_EN = 0x2401, /* ROH MAC commands */ @@ -345,6 +347,7 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_FD_B = 21, HCLGE_COMM_CAP_FEC_STATS_B = 25, HCLGE_COMM_CAP_LANE_NUM_B = 27, + HCLGE_COMM_CAP_WOL_B = 28, }; enum HCLGE_COMM_API_CAP_BITS { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 55306fe8a540..1bd95f04d327 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -2063,6 +2063,31 @@ static int hns3_get_link_ext_state(struct net_device *netdev, return -ENODATA; } +static void hns3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + 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; + + if (!hnae3_ae_dev_wol_supported(ae_dev) || !ops->get_wol) + return; + + ops->get_wol(handle, wol); +} + +static int hns3_set_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + 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; + + if (!hnae3_ae_dev_wol_supported(ae_dev) || !ops->set_wol) + return -EOPNOTSUPP; + + return ops->set_wol(handle, wol); +} + static const struct ethtool_ops hns3vf_ethtool_ops = { .supported_coalesce_params = HNS3_ETHTOOL_COALESCE, .supported_ring_params = HNS3_ETHTOOL_RING, @@ -2139,6 +2164,8 @@ static const struct ethtool_ops hns3_ethtool_ops = { .set_tunable = hns3_set_tunable, .reset = hns3_set_reset, .get_link_ext_state = hns3_get_link_ext_state, + .get_wol = hns3_get_wol, + .set_wol = hns3_set_wol, }; 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 43cada51d8cb..e6e94dae1b1a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -872,6 +872,32 @@ struct hclge_phy_reg_cmd { u8 rsv1[18]; }; +enum HCLGE_WOL_MODE { + HCLGE_WOL_PHY = BIT(0), + HCLGE_WOL_UNICAST = BIT(1), + HCLGE_WOL_MULTICAST = BIT(2), + HCLGE_WOL_BROADCAST = BIT(3), + HCLGE_WOL_ARP = BIT(4), + HCLGE_WOL_MAGIC = BIT(5), + HCLGE_WOL_MAGICSECURED = BIT(6), + HCLGE_WOL_FILTER = BIT(7), + HCLGE_WOL_DISABLE = 0, +}; + +#define HCLGE_SOPASS_MAX 6 + +struct hclge_wol_cfg_cmd { + __le32 wake_on_lan_mode; + u8 sopass[HCLGE_SOPASS_MAX]; + u8 sopass_size; + u8 rsv[13]; +}; + +struct hclge_query_wol_supported_cmd { + __le32 supported_wake_mode; + u8 rsv[20]; +}; + struct hclge_hw; int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num); enum hclge_comm_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 4e54f91f7a6c..88cb5c05bc43 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -11500,6 +11500,201 @@ static void hclge_uninit_rxd_adv_layout(struct hclge_dev *hdev) hclge_write_dev(&hdev->hw, HCLGE_RXD_ADV_LAYOUT_EN_REG, 0); } +static __u32 hclge_wol_mode_to_ethtool(u32 mode) +{ + __u32 ret = 0; + + if (mode & HCLGE_WOL_PHY) + ret |= WAKE_PHY; + + if (mode & HCLGE_WOL_UNICAST) + ret |= WAKE_UCAST; + + if (mode & HCLGE_WOL_MULTICAST) + ret |= WAKE_MCAST; + + if (mode & HCLGE_WOL_BROADCAST) + ret |= WAKE_BCAST; + + if (mode & HCLGE_WOL_ARP) + ret |= WAKE_ARP; + + if (mode & HCLGE_WOL_MAGIC) + ret |= WAKE_MAGIC; + + if (mode & HCLGE_WOL_MAGICSECURED) + ret |= WAKE_MAGICSECURE; + + if (mode & HCLGE_WOL_FILTER) + ret |= WAKE_FILTER; + + return ret; +} + +static u32 hclge_wol_mode_from_ethtool(__u32 mode) +{ + u32 ret = HCLGE_WOL_DISABLE; + + if (mode & WAKE_PHY) + ret |= HCLGE_WOL_PHY; + + if (mode & WAKE_UCAST) + ret |= HCLGE_WOL_UNICAST; + + if (mode & WAKE_MCAST) + ret |= HCLGE_WOL_MULTICAST; + + if (mode & WAKE_BCAST) + ret |= HCLGE_WOL_BROADCAST; + + if (mode & WAKE_ARP) + ret |= HCLGE_WOL_ARP; + + if (mode & WAKE_MAGIC) + ret |= HCLGE_WOL_MAGIC; + + if (mode & WAKE_MAGICSECURE) + ret |= HCLGE_WOL_MAGICSECURED; + + if (mode & WAKE_FILTER) + ret |= HCLGE_WOL_FILTER; + + return ret; +} + +int hclge_get_wol_supported_mode(struct hclge_dev *hdev, u32 *wol_supported) +{ + struct hclge_query_wol_supported_cmd *wol_supported_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_GET_SUPPORTED_MODE, + true); + wol_supported_cmd = (struct hclge_query_wol_supported_cmd *)desc.data; + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to query wol supported, ret = %d\n", ret); + return ret; + } + + *wol_supported = le32_to_cpu(wol_supported_cmd->supported_wake_mode); + + return 0; +} + +int hclge_get_wol_cfg(struct hclge_dev *hdev, u32 *mode) +{ + struct hclge_wol_cfg_cmd *wol_cfg_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_CFG, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get wol config, ret = %d\n", ret); + return ret; + } + + wol_cfg_cmd = (struct hclge_wol_cfg_cmd *)desc.data; + *mode = le32_to_cpu(wol_cfg_cmd->wake_on_lan_mode); + + return 0; +} + +static int hclge_set_wol_cfg(struct hclge_dev *hdev, + struct hclge_wol_info *wol_info) +{ + struct hclge_wol_cfg_cmd *wol_cfg_cmd; + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_WOL_CFG, false); + wol_cfg_cmd = (struct hclge_wol_cfg_cmd *)desc.data; + wol_cfg_cmd->wake_on_lan_mode = cpu_to_le32(wol_info->wol_current_mode); + wol_cfg_cmd->sopass_size = wol_info->wol_sopass_size; + memcpy(wol_cfg_cmd->sopass, wol_info->wol_sopass, HCLGE_SOPASS_MAX); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to set wol config, ret = %d\n", ret); + + return ret; +} + +static int hclge_update_wol(struct hclge_dev *hdev) +{ + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) + return 0; + + return hclge_set_wol_cfg(hdev, wol_info); +} + +static int hclge_init_wol(struct hclge_dev *hdev) +{ + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + int ret; + + if (!hnae3_ae_dev_wol_supported(hdev->ae_dev)) + return 0; + + memset(wol_info, 0, sizeof(struct hclge_wol_info)); + ret = hclge_get_wol_supported_mode(hdev, + &wol_info->wol_support_mode); + if (ret) { + wol_info->wol_support_mode = HCLGE_WOL_DISABLE; + return ret; + } + + return hclge_update_wol(hdev); +} + +static void hclge_get_wol(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + + wol->supported = hclge_wol_mode_to_ethtool(wol_info->wol_support_mode); + wol->wolopts = hclge_wol_mode_to_ethtool(wol_info->wol_current_mode); + if (wol_info->wol_current_mode & HCLGE_WOL_MAGICSECURED) + memcpy(wol->sopass, wol_info->wol_sopass, HCLGE_SOPASS_MAX); +} + +static int hclge_set_wol(struct hnae3_handle *handle, + struct ethtool_wolinfo *wol) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + struct hclge_wol_info *wol_info = &hdev->hw.mac.wol; + u32 wol_mode; + int ret; + + wol_mode = hclge_wol_mode_from_ethtool(wol->wolopts); + if (wol_mode & ~wol_info->wol_support_mode) + return -EINVAL; + + wol_info->wol_current_mode = wol_mode; + if (wol_mode & HCLGE_WOL_MAGICSECURED) { + memcpy(wol_info->wol_sopass, wol->sopass, HCLGE_SOPASS_MAX); + wol_info->wol_sopass_size = HCLGE_SOPASS_MAX; + } else { + wol_info->wol_sopass_size = 0; + } + + ret = hclge_set_wol_cfg(hdev, wol_info); + if (ret) + wol_info->wol_current_mode = HCLGE_WOL_DISABLE; + + return ret; +} + static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) { struct pci_dev *pdev = ae_dev->pdev; @@ -11696,6 +11891,11 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) /* Enable MISC vector(vector0) */ hclge_enable_vector(&hdev->misc_vector, true); + ret = hclge_init_wol(hdev); + if (ret) + dev_warn(&pdev->dev, + "failed to wake on lan init, ret = %d\n", ret); + hclge_state_init(hdev); hdev->last_reset_time = jiffies; @@ -12075,6 +12275,8 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) hclge_init_rxd_adv_layout(hdev); + (void)hclge_update_wol(hdev); + dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n", HCLGE_DRIVER_NAME); @@ -13105,6 +13307,8 @@ static const struct hnae3_ae_ops hclge_ops = { .get_link_diagnosis_info = hclge_get_link_diagnosis_info, .clean_vf_config = hclge_clean_vport_config, .get_dscp_prio = hclge_get_dscp_prio, + .get_wol = hclge_get_wol, + .set_wol = hclge_set_wol, }; 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 495b639b0dc2..3be92ceb5744 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -249,6 +249,13 @@ enum HCLGE_MAC_DUPLEX { #define QUERY_SFP_SPEED 0 #define QUERY_ACTIVE_SPEED 1 +struct hclge_wol_info { + u32 wol_support_mode; /* store the wake on lan info */ + u32 wol_current_mode; + u8 wol_sopass[HCLGE_SOPASS_MAX]; + u8 wol_sopass_size; +}; + struct hclge_mac { u8 mac_id; u8 phy_addr; @@ -268,6 +275,7 @@ struct hclge_mac { u32 user_fec_mode; u32 fec_ability; int link; /* store the link status of mac & phy (if phy exists) */ + struct hclge_wol_info wol; struct phy_device *phydev; struct mii_bus *mdio_bus; phy_interface_t phy_if; @@ -1141,4 +1149,6 @@ int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len); int hclge_push_vf_link_status(struct hclge_vport *vport); int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en); int hclge_mac_update_stats(struct hclge_dev *hdev); +int hclge_get_wol_supported_mode(struct hclge_dev *hdev, u32 *wol_supported); +int hclge_get_wol_cfg(struct hclge_dev *hdev, u32 *mode); #endif -- 2.30.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-02-06 13:50 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-01-04 1:34 [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 Hao Lan 2023-01-04 1:34 ` [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query Hao Lan 2023-01-04 2:10 ` Andrew Lunn 2023-01-04 12:57 ` Hao Lan 2023-01-04 15:00 ` Andrew Lunn 2023-01-04 1:34 ` [PATCH net-next 2/2] net: hns3: support debugfs for wake on lan Hao Lan 2023-01-04 2:12 ` Andrew Lunn -- strict thread matches above, loose matches on Subject: below -- 2023-02-06 13:49 [PATCH net-next 0/2] net: hns3: support wake on lan for hns3 Hao Lan 2023-02-06 13:49 ` [PATCH net-next 1/2] net: hns3: support wake on lan configuration and query Hao Lan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).